/**
 * @file nb_comp.c
 * @brief
 *
 * @version 0.1
 * @date 2023-09-06
 *
 * @copyright  Copyright (c) 2020~2030 ShenZhen dingxintongchuang Technology Co., Ltd.
 * All rights reserved.
 *
 * @note          鼎新同创・智能锁
 *
 * @par 修改日志:
 * <1> 2023-09-06 v0.1 tianshidong 创建初始版本
 * *************************************************************************
 */
#include "component.h"
#include "device.h"
#include "nb_comp.h"
#include "nb_main.h"
#include "debug_config.h"
#include "application.h"

#define EVENT_NB_POLL_DATA (0x00000001)               //轮询串口事件
#define EVENT_NB_POWER_ON (0x00000002)                //开机事件
#define EVENT_NB_READ_NB_BUFFDATA (0x00000004)        //读取NB缓存数据
#define EVENT_NB_IO_PULL_UP_WAKE (0x00000008)         //唤醒和复位IO口状态置位事件
#define EVENT_NB_IO_PULL_UP_RESEET (0x00000010)       //唤醒和复位IO口状态置位事件
#define EVENT_NB_IO_RUN_STATUS_CHECK (0x00000020)     // NB模组运行状态检查
#define EVENT_NB_IO_SLEEP_CHECK (0x00000040)          // NB模组假睡状态，如果再休眠状态，发送唤醒后没有收到'+HIB Exit',2S后直接读取数据
#define EVENT_NB_CONTROL_ENTER_PSM_CHECK (0x00000080) //控制模组进入休眠检查
#define EVENT_NB_TX_QUEUE (0x00000100)                //轮询NB发送队列事件
#define EVENT_NB_RX_QUEUE (0x00000200)                //轮询NB发送队列事件
#define EVENT_NB_ENTER_PSM (0x00000400)               //延迟进入休眠
#define EVENT_AEP_OTA_TX_QUEUE (0x00000800)           // AEP OTA 发送队列事件
#define NB_RX_BUFF_LEN (512 * 2)                      // NB环形缓冲区长度
#define NB_VIRTUAL_UART vUART_1                       // NB虚拟串口设备
#define NB_VIRTUAL_RESET_PIN vPIN_C37                 //虚拟复位口
#define NB_VIRTUAL_WAKEUP_PIN vPIN_C36                //虚拟唤醒口

#define NB_SEND_QUEUE_LEN (10)          //发送队列消息最大数量
static SuperQueueHandle_t NB_SendQueue; ///< 发送队列句柄
static uint8_t NbtxQueueFlag = 0;

#define NB_RECV_QUEUE_LEN (10)          //接收队列消息最大数量
static SuperQueueHandle_t NB_RecvQueue; ///< 接收队列句柄
static uint8_t NbRxQueueFlag = 0;

#define AEP_OTA_TX_QUEUE_LEN (10)         //发送队列消息最大数量
static SuperQueueHandle_t AepOta_TxQueue; ///< 发送队列句柄
static uint8_t AepOtaTxQueueFlag = 0;

#define NB_NV_ADDR_AES_KEY 0 // AES密钥存储偏移地址

static void NB_TASK_Send_cmd(uint8_t cmd);
static void NB_TASK_send_data(uint8_t *data, uint16_t len);
static void NB_TASK_at_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_reset_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_ATE_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_CMEE_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_inqiury_IMEI_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_inqiury_vsrsion_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_check_SIM_status_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_inquiry_CGATT_status_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_inquiry_CEREG_status_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_get_IMSI_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_inquery_CSQ_callback(uint8_t *pData, uint16_t len);

static void NB_TASK_inquiry_IP_status_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_set_AEP_port_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_logIn_AEP_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_Get_Cclk_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_PSM_status_log_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_PSM_enable_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_ECCFG_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_ECNBIOTRAI_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_set_readBuff_mode_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_read_data_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_logOut_AEP_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_send_test_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_PSM_status_close_PSM_change_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_PSM_status_open_PSM_change_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_inquiry_AEP_status_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_get_ICCID_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_inquiry_ECBCINFO_status_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_inquiry_ECSTATUS_PHY_status_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_inquiry_ECSTATUS_RRC_status_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_send_ECVOTECHK_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_Stop_Into_PSM_change_callback(uint8_t *pData, uint16_t len);
static void NB_TASK_send_ATE_callback(uint8_t *pData, uint16_t len);

#pragma pack(1)
/* 命令包接收状态信息：记录蓝牙和Uart两个设备的发送状态 */
static struct
{
    uint16_t protocolCount;                  //协议解析计数变量
    uint16_t protocolDataCount;              // 4个变量，注意何时清空
    uint8_t protocolDataBuf[NB_RX_BUFF_LEN]; //协议解析数据缓存
    uint8_t protocolBuf[NB_RX_BUFF_LEN];     //协议解析缓存
    enum
    {
        RX_STA_IDLE,     //空闲
        RX_STA_SEND_ACK, //正在发送多包ACK
    } status;
} CmdPacketRxInfo;

#pragma pack()
enum
{
    TX_STA_IDLE,     //空闲
    TX_STA_WAIT_ACK, //等待ACK
} tx_status;
static struct
{
    uint8_t cmdLen;               //命令长度
    uint8_t resendTimes;          //重发次数
    uint16_t resendInterval;      //重发间隔时间
    NB_TASK_response_callback cb; //命令执行回调
    char *cmdString;              //命令字符
} cmdSendInfo[CURRENT_SEND_MAX_STATUS] =
    {
        /* 初始化状态无效指令 */
        [CURRENT_SEND_INVALID] = {0, 0, 0, NULL},
        /* 开机指令，建议上电后3s后发送 */
        [CURRENT_SEND_AT] = {strlen(NWY_AT_CMD_AT), NB_NORMAL_CMD_RESEND_TIMES, 1000, NB_TASK_at_callback, NWY_AT_CMD_AT},
        /* 查询IMEI号指令 */
        [CURRENT_SEND_CGSN] = {strlen(NWY_AT_CMD_CGSN), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_inqiury_IMEI_callback, NWY_AT_CMD_CGSN},
        /* 查询NB模组版本号 */
        [CURRENT_SEND_CGMR] = {strlen(NWY_AT_CMD_CGMR), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_inqiury_vsrsion_callback, NWY_AT_CMD_CGMR},
        /* 检查SIM卡状态 */
        [CURRENT_SEND_CPIN] = {strlen(NWY_AT_CMD_CPIN), 15, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_check_SIM_status_callback, NWY_AT_CMD_CPIN},
        /* 获取卡IMSI */
        // [CURRENT_SEND_CIMI] = {strlen(NWY_AT_CMD_CIMI), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_get_IMSI_callback, NWY_AT_CMD_CIMI},
        /* 获取卡ICCID */
        [CURRENT_SEND_ICCID] = {strlen(NWY_AT_CMD_ICCID), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_get_ICCID_callback, NWY_AT_CMD_ICCID},
        /* 获取信号强度 */
        [CURRENT_SEND_CSQ] = {strlen(NWY_AT_CMD_CSQ), 40, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_inquery_CSQ_callback, NWY_AT_CMD_CSQ},
        /* 查询网络附着情况 */
        [CURRENT_SEND_CGATT] = {strlen(NWY_AT_CMD_CGATT), 60, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_inquiry_CGATT_status_callback, NWY_AT_CMD_CGATT},
        /* 查询网络注册情况 */
        [CURRENT_SEND_CEREG] = {strlen(NWY_AT_CMD_CEREG), 60, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_inquiry_CEREG_status_callback, NWY_AT_CMD_CEREG},
        /* 获取NB时间 */
        [CURRENT_SEND_CCLK] = {strlen(NWY_AT_CMD_CCLK), NB_NORMAL_CMD_RESEND_TIMES, 500, NB_TASK_Get_Cclk_callback, NWY_AT_CMD_CCLK},
        /* 返回服务小区和邻区信息 */
        // [CURRENT_SEND_ECBCINFO] = {strlen(NWY_AT_CMD_ECBCINFO), NB_NORMAL_CMD_RESEND_TIMES, 8000, NB_TASK_inquiry_ECBCINFO_status_callback, NWY_AT_CMD_ECBCINFO},
        /* 返回 UE 端关键参数状态 RRC*/
        [CURRENT_SEND_ECSTATUS_RRC] = {strlen(NWY_AT_CMD_ECSTATUS_RRC), NB_NORMAL_CMD_RESEND_TIMES, 5000, NB_TASK_inquiry_ECSTATUS_RRC_status_callback, NWY_AT_CMD_ECSTATUS_RRC},
        /* 返回 UE 端关键参数状态 phy*/
        [CURRENT_SEND_ECSTATUS_PHY] = {strlen(NWY_AT_CMD_ECSTATUS_PHY), NB_NORMAL_CMD_RESEND_TIMES, 5000, NB_TASK_inquiry_ECSTATUS_PHY_status_callback, NWY_AT_CMD_ECSTATUS_PHY},

        /* 复位模组指令，最大响应时间5s */
        [CURRENT_SEND_RESET] = {strlen(NWY_AT_CMD_RESET), 3, 1000, NB_TASK_reset_callback, NWY_AT_CMD_RESET},

        /* 关闭/开启 回显指令 */
        [CURRENT_SEND_ATE_CLOSE] = {strlen(NWY_AT_CMD_ATE_CLOSE), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_ATE_callback, NWY_AT_CMD_ATE_CLOSE},
        // [CURRENT_SEND_ATE_OPEN] = {strlen(NWY_AT_CMD_ATE_OPEN), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_ATE_callback, NWY_AT_CMD_ATE_OPEN},
        // [CURRENT_SEND_CMEE] = {strlen(NWY_AT_CMD_CMEE), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_CMEE_callback, NWY_AT_CMD_CMEE},
        /* 查询IP地址 */
        [CURRENT_SEND_CGPADDR] = {strlen(NWY_AT_CMD_CGPADDR), 10, 1000, NB_TASK_inquiry_IP_status_callback, NWY_AT_CMD_CGPADDR},
        /* 设置电信AEP平台地址和端口 */
        [CURRENT_SEND_CTM2MSETPM] = {strlen(NWY_AT_CMD_CTM2MSETPM), NB_NORMAL_CMD_RESEND_TIMES, 500, NB_TASK_set_AEP_port_callback, NWY_AT_CMD_CTM2MSETPM},
        /* 登录AEP平台 */
        [CURRENT_SEND_CTM2MREG] = {strlen(NWY_AT_CMD_CTM2MREG), NB_NORMAL_CMD_RESEND_TIMES, 1500, NB_TASK_logIn_AEP_callback, NWY_AT_CMD_CTM2MREG},
        /* 查询AEP平台登录状态 */
        [CURRENT_SEND_INQUIRY_CTM2MREG] = {strlen(NWY_AT_CMD_INQUIRY_CTM2MREG), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_inquiry_AEP_status_callback, NWY_AT_CMD_INQUIRY_CTM2MREG},
        /* 设置平台数据读取模式 */
        [CURRENT_SEND_CTM2MRMODE] = {strlen(NWY_AT_CMD_CTM2MRMODE), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_set_readBuff_mode_callback, NWY_AT_CMD_CTM2MRMODE},
        /* 读取平台缓存数据 */
        [CURRENT_SEND_CTM2MREAD] = {strlen(NWY_AT_CMD_CTM2MREAD), 3, 1000, NB_TASK_read_data_callback, NWY_AT_CMD_CTM2MREAD},
        /* 注销平台请求 */
        [CURRENT_SEND_CTM2MDEREG] = {strlen(NWY_AT_CMD_CTM2MDEREG), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_logOut_AEP_callback, NWY_AT_CMD_CTM2MDEREG},
        /* 发送数据到平台 */
        [CURRENT_SEND_CTM2MSEND] = {strlen(NWY_AT_CMD_CTM2MSEND_HEAD), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_send_test_callback, NWY_AT_CMD_CTM2MSEND_HEAD},

        /* 使能低功耗模式 */
        [CURRENT_SEND_CPSMS] = {strlen(NWY_AT_CMD_CPSMS), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_PSM_enable_callback, NWY_AT_CMD_CPSMS},
        /* 关闭低功耗模式 */
        [CURRENT_SEND_PSM_CLOSE] = {strlen(NWY_AT_CMD_PSM_CLOSE), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_PSM_status_close_PSM_change_callback, NWY_AT_CMD_PSM_CLOSE},
        /* 开启低功耗模式 */
        [CURRENT_SEND_PSM_OPEN] = {strlen(NWY_AT_CMD_PSM_OPEN), NB_NORMAL_CMD_RESEND_TIMES, 1000, NB_TASK_PSM_status_open_PSM_change_callback, NWY_AT_CMD_PSM_OPEN},
        /* 设置3324定时器时间，重启生效 */
        [CURRENT_SEND_ECCFG] = {strlen(NWY_AT_CMD_ECCFG), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_ECCFG_callback, NWY_AT_CMD_ECCFG},
        /* 释放RRC连接 */
        [CURRENT_SEND_ECNBIOTRAI] = {strlen(NWY_AT_CMD_ECNBIOTRAI), NB_NORMAL_CMD_RESEND_TIMES, 1000, NB_TASK_ECNBIOTRAI_callback, NWY_AT_CMD_ECNBIOTRAI},
        /* 进入或者退出 PSM模式， log信息上报 */
        [CURRENT_SEND_ECPURC] = {strlen(NWY_AT_CMD_ECPURC), NB_NORMAL_CMD_RESEND_TIMES, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_PSM_status_log_callback, NWY_AT_CMD_ECPURC},

        /* 退出低功耗，需要先发送数据给AEP，然后再读取数据 */
        [CURRENT_SEND_TEST] = {strlen(NWY_AT_CMD_SEND_DATA_TEST), 5, 1000, NB_TASK_send_test_callback, NWY_AT_CMD_SEND_DATA_TEST},
        /* 产测数据 */
        [CURRENT_SEND_ATE] = {strlen(NWY_AT_CMD_SEND_ATE_DATA), 3, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_send_ATE_callback, NWY_AT_CMD_SEND_ATE_DATA},
        /* 查询任务投票状态，分析睡眠失败的原因 */
        // [CURRENT_SEND_ECVOTECHK] = {strlen(NWY_AT_CMD_ECVOTECHK), 1, NB_NORMAL_CMD_RESEND_INTERVAL, NB_TASK_send_ECVOTECHK_callback, NWY_AT_CMD_ECVOTECHK},
        /* 中止进入功耗 */
        [CURRENT_SEND_STOP_INTOPSM] = {strlen(NWY_AT_CMD_PSM_CLOSE), NB_NORMAL_CMD_RESEND_TIMES, 1000, NB_TASK_Stop_Into_PSM_change_callback, NWY_AT_CMD_PSM_CLOSE},

};
#define READ_EMPTY_MAX 3
NB_sendManage_stu_t nbSendManage;                             //指令发送状态管理
static uint8_t uart_tx_buffer[NB_SEND_BUFFER_SIZE * 2] = {0}; //发送缓存
static uint16_t tx_ctrl_flg = 0;                              //发送数据长度
static uint8_t runStatus = NB_STATUS_INIT;                    // NB模组运行状态
RingBufferHandle_t nbRbHandle = NULL;                         // NB接收缓冲区句柄
static uint8_t resetCount = 0;                                //复位次数管理
static uint8_t recvDataNumber = 0;                            //需要读取数据包的条数
static uint8_t protocolVersion[3] = {0};                      //协议版本
static uint8_t aesKey[16] = {0};                              // lot下发的AESkey,初始时的AESkey, mac+iemi+mac，后续用服务器下发的
static Nb_ueImportantPara_t nbUeParam;                        // UE关键状态参数
static uint8_t readNextFlag = RESET;                          //发送读取命令时读取下一包数据标志位；只有收到OK后，才允许读下一包
static uint8_t readDataFlag = RESET;                          //读取NB缓存数据标志，只有蓝牙让NB读时才读取，否则只来+CTM2MRECV时，不读取
static uint8_t selfCheckFlag = RESET;                         //自检时，只读取CSQ，不跑初始化流程
static uint8_t AepOtaMark = RESET;                            // OTA升级标志
static uint8_t readEmptyCount = READ_EMPTY_MAX;               //读取NB缓冲区计数
static uint8_t wakeup_count = 0;                              //唤醒NB动作执行次数
static uint8_t stopIntoPSM = 0;                               //停止进入休眠标志
/**
 * @brief  XOR校验
 * @note
 *
 * @param  pData：数据指针
 * @param  len：数据长度
 * @return 成功返回校验和
 */
static uint8_t NBTask_CalcCheckXor(uint8_t *pData, uint16_t len)
{
    uint16_t i = 0;
    uint8_t x = 0;

    for (i = 0; i < len; i++)
    {
        x = x ^ (*(pData + i));
    }

    return x;
}

/**
 * @brief 字符串转换为十六进制串
 *
 * @param [in] pAscii 字符串
 * @param [in] pHex 十六进制串
 * @param [in] strLen 字符串长度
 * @return uint16_t 返回十六进制串的长度
 *
 * @note "1A2B3C4D"  --->  0x1A2B3C4D
 */
static uint16_t NB_TASK_str_to_hex(uint8_t *pAscii, uint8_t *pHex, uint16_t strLen)
{
    uint8_t byteData;
    uint8_t tempData;
    uint16_t i;

    if (0 != strLen % 2)
    {
        NB_TASK_LOG_E("NB str to hex strLen is error");
        return 0;
    }

    for (i = 0; i < strLen / 2; i++)
    {
        tempData = *pAscii++;
        if (tempData >= '0' && tempData <= '9')
        {
            tempData -= '0';
        }
        else if (tempData >= 'A' && tempData <= 'F')
        {
            tempData = tempData + 10 - 'A';
        }
        else if (tempData >= 'a' && tempData <= 'f')
        {
            tempData = tempData + 10 - 'a';
        }
        else
        {
            return 0;
        }
        byteData = (tempData << 4);

        tempData = *pAscii++;
        if (tempData >= '0' && tempData <= '9')
        {
            tempData -= '0';
        }
        else if (tempData >= 'A' && tempData <= 'F')
        {
            tempData = tempData + 10 - 'A';
        }
        else if (tempData >= 'a' && tempData <= 'f')
        {
            tempData = tempData + 10 - 'a';
        }
        else
        {
            return 0;
        }
        byteData += tempData;
        pHex[i] = byteData;

        // NB_TASK_LOG_D("%02x ",pHex[i]);
    }
    // NB_TASK_LOG_D("\nlen[%d]\n",strLen / 2);
    return (strLen / 2);
}
/**
 * @brief 十六进制转换为字符串
 *
 * @param [in] pAscii 字符串指针
 * @param [in] pHex 十六进制指针
 * @param [in] hexLen 十六进制长度
 * @return uint16_t 转换后的字符串长度
 *
 * @note 0x1A2B3C4D  --->  "1A2B3C4D"
 */
static uint16_t NB_TASK_hex_to_str(uint8_t *pAscii, uint8_t *pHex, uint16_t hexLen)
{
    uint8_t tempData;
    uint16_t i;
    uint8_t *pStr = pAscii;

    if (pAscii == NULL || pHex == NULL)
    {
        NB_TASK_LOG_E("NB hex to str Point is NULL");
    }

    for (i = 0; i < hexLen; i++)
    {
        tempData = (pHex[i] & 0xF0) >> 4;
        if (tempData < 10)
        {
            tempData += '0';
        }
        else
        {
            tempData = tempData - 10 + 'A';
        }
        *pStr++ = tempData;

        tempData = (pHex[i] & 0x0F);
        if (tempData < 10)
        {
            tempData += '0';
        }
        else
        {
            tempData = tempData - 10 + 'A';
        }
        *pStr++ = tempData;
    }
    // NB_TASK_LOG_D("\n%s   len[%d]\n", pAscii, 2 * hexLen);
    return (2 * hexLen);
}
/**
 * @brief   发送数据给应用层（COMP->应用层)
 *
 * @note
 */
static void NBTask_MessagePublish(uint16_t len, uint8_t *pData, uint8_t sid, uint16_t mid, uint8_t type)
{
    NbPublishMsg_t *msg = NULL;
    msg = (NbPublishMsg_t *)OSAL_Malloc(len + sizeof(NbPublishMsg_t));
    if (msg == NULL)
    {
        BLE_TASK_LOG_E("msg publish err\r\n");
        return;
    }
    memset(msg, 0, len + sizeof(NbPublishMsg_t));
    msg->type = type;
    msg->MID = mid;
    msg->SID = sid;
    msg->len = len;
    if (pData != NULL)
    {
        memcpy(msg->pData, pData, len);
    }
    OSAL_MessagePublish(msg, len + sizeof(NbPublishMsg_t));
    OSAL_Free(msg);
}

/**
 * @brief 获取NB模组工作状态
 *
 * @return uint8_t
 *
 * @note
 */
static uint8_t NB_TASK_get_nb_status(void)
{
    return runStatus;
}

static uint8_t BleConnectStatus = 0;
/**
 * @brief 设置蓝牙连接状态
 *
 * @param [in] sta  1:蓝牙已连接  0：蓝牙已断开
 *
 * @note
 */
static void Set_BleConnectStatust(uint8_t sta)
{
    BleConnectStatus = sta;
}

static void NB_TASK_wake_NB(void)
{
    NB_TASK_LOG_I("Control NB exit PSM, runstatus:%d", runStatus);
    switch (runStatus)
    {
    case NB_STATUS_WAITPSM:
        if (tx_ctrl_flg)
        {
            tx_ctrl_flg = 0;
            NB_TASK_LOG_E("TX buff not empty !");
        }
        NB_TASK_Send_cmd(CURRENT_SEND_STOP_INTOPSM);
        stopIntoPSM = 1;
        break; // TODO:是否注释掉改行
    case NB_STATUS_CONNECTED_AEP:
        NB_TASK_Send_cmd(CURRENT_SEND_TEST);
        break; // TODO:是否注释掉改行
    default:
        if (wakeup_count == 0)
        {
            wakeup_count = 1;
            Device_Write(NB_VIRTUAL_WAKEUP_PIN, NULL, 0, 1);
            OSAL_EventRepeatCreate(COMP_NB, EVENT_NB_IO_PULL_UP_WAKE, NB_CONTROL_IO_DOWN_TIMEROUT, EVT_PRIORITY_MEDIUM);
        }
        break;
    }
}
static uint8_t EnterPsmMode;
static void NB_TASK_Enter_PSM(void)
{
    NB_TASK_LOG_I("Control NB enter PSM, runstatus:%d, AepOtaMark:%d, readEmptyCount:%d", runStatus, AepOtaMark, readEmptyCount);

    if (AepOtaMark == RESET && readEmptyCount == READ_EMPTY_MAX)
    {
        if (EnterPsmMode == NB_CONTROL_ENTER_PSM_NOT_RAI)
        {
            NB_TASK_Send_cmd(CURRENT_SEND_PSM_OPEN);
        }
        else
        {
            NB_TASK_Send_cmd(CURRENT_SEND_ECNBIOTRAI);
        }
        runStatus = NB_STATUS_WAITPSM;
    }
}
static void NB_TASK_Enter_PSM_Check(uint8_t cmd)
{
    EnterPsmMode = cmd;
    if (NbtxQueueFlag || AepOtaTxQueueFlag || nbSendManage.SendStatus != TX_STA_IDLE)
    {
        OSAL_EventRepeatCreate(COMP_NB, EVENT_NB_ENTER_PSM, 100, EVT_PRIORITY_MEDIUM);
    }
    else
    {
        NB_TASK_Enter_PSM();
    }
}

/**
 * @brief 控制模组复位或者唤醒
 *
 * @param [in] cmd
 * @return uint8_t
 *
 * @note
 */
static void NB_TASK_control_nb_status_handle(NB_control_status_enum_t cmd)
{
#if (TEST_NB_RF)
    if (cmd == NB_CONTROL_EXIT_PSM)
    {
        if (runStatus >= NB_STATUS_RUNNING)
        {
            NB_TASK_send_data("030D05", 6);
        }
    }
    else if (cmd == NB_CONTROL_RESET)
    {
        NB_TASK_LOG_I("Control NB HARD RESET");
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
        Device_Write(NB_VIRTUAL_RESET_PIN, NULL, 0, 1);
        OSAL_EventSingleCreate(COMP_NB, EVENT_NB_IO_PULL_UP_RESEET, NB_CONTROL_IO_DOWN_TIMEROUT, EVT_PRIORITY_MEDIUM);
    }
#else
    switch (cmd)
    {
    case NB_CONTROL_ENTER_PSM:
    case NB_CONTROL_ENTER_PSM_NOT_RAI:
        NB_TASK_Enter_PSM_Check(cmd);
        break;

    case NB_CONTROL_EXIT_PSM:
        OSAL_EventDelete(COMP_NB, EVENT_NB_ENTER_PSM);
        NB_TASK_wake_NB();
        break;

    case NB_CONTROL_RESET:
        runStatus = NB_STATUS_RESET;
        NB_TASK_LOG_I("Control NB HARD RESET");
        Device_Write(NB_VIRTUAL_WAKEUP_PIN, NULL, 0, 0);
        wakeup_count = 0;
        OSAL_EventDelete(COMP_NB, EVENT_NB_IO_PULL_UP_WAKE);
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
        Device_Write(NB_VIRTUAL_RESET_PIN, NULL, 0, 1);
        OSAL_EventSingleCreate(COMP_NB, EVENT_NB_IO_PULL_UP_RESEET, NB_CONTROL_IO_DOWN_TIMEROUT, EVT_PRIORITY_MEDIUM);
        break;

    default:
        break;
    }
#endif /*TEST_NB_RF*/
}
/**
 * @brief 解析BLE转发的NB数据
 *
 * @param [in] pData
 * @param [in] dataLen
 * @return uint8_t
 *
 * @note
 */
static uint8_t NB_TASK_receive_ble_convert_data_handle(uint8_t *pData, uint8_t dataLen)
{
    uint8_t payloadHex[NB_RX_BUFF_LEN] = {0};
    uint8_t desData[NB_RX_BUFF_LEN] = {0};
    NB_ble_forward_protocol_publish_stu_t *pPublishiMsg = desData;

    if (pData == NULL || dataLen == 0 || dataLen > NB_RX_BUFF_LEN)
    {
        NB_TASK_LOG_E("NB receive Ble data or len error, len:%d", dataLen);
        return 0;
    }

    memcpy(payloadHex, pData, dataLen);

    /* AES128-ECB解密 */
    FUNC_BLE_LOG_HEX("aesKey:", aesKey, sizeof(aesKey));

    OSAL_Crypto(AES128_DECRYPTION, payloadHex, dataLen, desData, aesKey);
    NB_TASK_LOG_HEX("DECRYPTION HEX:", desData, dataLen);

    pPublishiMsg->dataLen = OSAL_SWAP16(pPublishiMsg->dataLen);

    uint8_t checkXor = NBTask_CalcCheckXor(pPublishiMsg->protocolVersion, pPublishiMsg->dataLen + 7);

    if (checkXor == pPublishiMsg->data[pPublishiMsg->dataLen - 1])
    {
        NBTask_MessagePublish(dataLen, &pPublishiMsg->cmd, pPublishiMsg->SID, 0, PUBLISH_APP_NB_DATA);
    }
    else
    {
        NB_TASK_LOG_E("checkXor:0x%x, xor:0x%x", checkXor, pPublishiMsg->data[pPublishiMsg->dataLen - 1]);
    }
}
/**
 * @brief 接收云平台数据处理
 *
 * @param [in] pStr
 * @param [in] strLen
 * @return uint8_t
 *
 * @note
 */
static void NB_TASK_receive_lot_data_handle(uint8_t *pStr, uint16_t strLen)
{
    uint8_t payloadHex[NB_RX_BUFF_LEN] = {0}; //字符串转换为HEX串的密文
    uint8_t desData[NB_RX_BUFF_LEN] = {0};    //解密后的 CMD+DATA，明文
    uint16_t payloadHexLen = 0;
    uint16_t deCryptoLen = 0;
    uint16_t publishDataLen = 0;
    NB_protocol_stu_t *pNbPraseData = NULL;
    NB_protocol_stu_t *pNbPublishiData = (NB_protocol_stu_t *)desData;

    /* 明文字符串转换为HEX串 */
    payloadHexLen = NB_TASK_str_to_hex(pStr, payloadHex, strLen);

    if (memcmp(pStr, "FFFE01", 6) == 0)
    {
        AepOta_protocol_stu_t *pAepOtaCmd = (AepOta_protocol_stu_t *)&payloadHex;
        uint16_t crc = OSAL_SWAP16(pAepOtaCmd->crc);
        pAepOtaCmd->crc = 0;
        if (crc == do_crc(0x0000, (uint8_t *)pAepOtaCmd, OSAL_SWAP16(pAepOtaCmd->dataLen) + 8))
        {
            NBTask_MessagePublish(OSAL_SWAP16(pAepOtaCmd->dataLen), &pAepOtaCmd->data, pAepOtaCmd->cmd, 0, PUBLISH_APP_AEP_OTA);
        }
        else
        {
            NB_TASK_LOG_E("APE OTA pack do_crc check err");
        }
        return;
    }
    pNbPraseData = (NB_protocol_stu_t *)payloadHex;
    deCryptoLen = OSAL_SWAP16(pNbPraseData->dataLen);
    memcpy(desData, payloadHex, sizeof(desData));

    NB_TASK_LOG_D("deCryptoLen:%d, 0x:%x", deCryptoLen, deCryptoLen);
    FUNC_BLE_LOG_HEX("aesKey:", aesKey, sizeof(aesKey));

    /* AES128-ECB解密 */
    OSAL_Crypto(AES128_DECRYPTION, &pNbPraseData->cmd, deCryptoLen, &pNbPublishiData->cmd, aesKey);

    NB_TASK_LOG_HEX("DECRYPTION HEX:", &pNbPublishiData->cmd, deCryptoLen);

    /* 剔除掉明文中填充的0 */
    uint8_t checkXor = NBTask_CalcCheckXor(&desData[3], 7 + deCryptoLen);
    if (checkXor != payloadHex[payloadHexLen - 2])
    {
        // recvDataNumber += 4; //校验出错，多读4次缓存
        NB_TASK_LOG_E("checkXor:0x%x, xor:0x%x", checkXor, payloadHex[payloadHexLen - 2]);
    }
    else
    {
        publishDataLen = OSAL_SWAP16(pNbPublishiData->dataLen);
        // memcpy(protocolVersion, pNbPublishiData->protocolVersion, sizeof(pNbPublishiData->protocolVersion));
        if (BleConnectStatus == 1 && NbRxQueueFlag == 0)
        {
            NBTask_MessagePublish(publishDataLen, &pNbPublishiData->cmd, pNbPublishiData->SID, pNbPublishiData->MID, PUBLISH_APP_NB_DATA);
        }
        else
        {
            if (SUCCESS == OSAL_QueueSend(NB_RecvQueue, (void *)pNbPublishiData, (publishDataLen + 10), RESET))
            {
                NB_TASK_LOG_I("NB_RecvQueue input success");
                if (NbRxQueueFlag == 0)
                {
                    NbRxQueueFlag = 1;
                    OSAL_EventRepeatCreate(COMP_NB, EVENT_NB_RX_QUEUE, 200, EVT_PRIORITY_MEDIUM);
                }
            }
            else
            {
                NB_TASK_LOG_E("NB_RecvQueue input ERR");
            }
        }
    }
}

/**
 * @brief  获取发送缓存区的状态
 * @note
 *
 * @return 缓存区为空返回0
 */
static uint8_t NB_TASK_GetTxBufferStatus(void)
{
    return tx_ctrl_flg;
}
/**
 * @brief  加载待发送的数据
 * @note   将要发出的数据，填入发送缓存区
 *
 * @param  pData：数据指针
 * @param  len：数据长度
 * @return 成功返回SUCCESS，失败返回ERROR
 */
static ErrorStatus NB_TASK_LoadingDataToBeSent(uint8_t *pData, uint16_t len)
{
    uint8_t *pSendBuf = uart_tx_buffer;
    if (tx_ctrl_flg == 0)
    {
        tx_ctrl_flg = len;
        memcpy(pSendBuf, pData, len);
        return SUCCESS;
    }
    NB_TASK_LOG_E("Loading Tx data failed\r\n");
    return ERROR;
}

/**
 * @brief  处理发送缓存
 * @note   将发送缓存区的数据，通过串口发出，并处理Int控制逻辑
 *
 */
static void NB_TASK_ProcessTxBuffer(void)
{
    uint8_t *pSendBuf = uart_tx_buffer;

    if (tx_ctrl_flg > 0)
    {
        /* 调用硬件层write接口，发出数据 */
        NB_TASK_LOG_D("\r\n\r\n\r\nSend cmd:%.*s", tx_ctrl_flg, pSendBuf);
        // NB_TASK_LOG_HEX("Uart send packet", pSendBuf, tx_ctrl_flg & 0X7FFF);
        Device_Write(NB_VIRTUAL_UART, pSendBuf, tx_ctrl_flg & 0X7FFF, 0);
        tx_ctrl_flg = 0;
    }
}

/**
 * @brief 复位 重发状态和缓存
 *
 *
 * @note
 */
static void NB_TASK_reset_resend_info(void)
{
    memset(&nbSendManage, 0, sizeof(nbSendManage));
    nbSendManage.SendStatus = TX_STA_IDLE;
}

/**
 * @brief 发送数据到云平台
 *
 * @param [in] data 数据（字符串类型）
 * @param [in] len 数据长度（字符串长度）
 *
 * @note
 */
static void NB_TASK_send_data(uint8_t *data, uint16_t len)
{
    uint8_t sendBuff[NB_SEND_BUFFER_SIZE * 2] = {0};
    uint16_t cmdAreaLen = 0;
    uint8_t sendCmdType = CURRENT_SEND_CTM2MSEND;

    cmdAreaLen = cmdSendInfo[sendCmdType].cmdLen;

    if (data == NULL || len == 0)
    {
        NB_TASK_LOG_E("NB send data or len ERROR");
        return;
    }

    if (cmdAreaLen + len > (NB_SEND_BUFFER_SIZE * 2))
    {
        NB_TASK_LOG_E("NB send data len overflow");
        return;
    }

    //只有发送读取标志时，才主动读取NB缓存数据
    if (memcmp(data, "030D05", len) == 0)
    {
        NB_TASK_LOG_W("Allow data to be read");
        // readDataFlag = SET;
    }

    memcpy(sendBuff, cmdSendInfo[sendCmdType].cmdString, cmdAreaLen);
    memcpy(&sendBuff[cmdAreaLen], data, len);
    sendBuff[cmdAreaLen + len] = '\r';

    nbSendManage.curSendCmd = sendCmdType;
    nbSendManage.SendStatus = TX_STA_WAIT_ACK;
    nbSendManage.resendCount = 1;
    nbSendManage.resendTimes = cmdSendInfo[sendCmdType].resendTimes;
    nbSendManage.resendInterval = cmdSendInfo[sendCmdType].resendInterval;
    nbSendManage.TimeStamp = OSAL_GetTickCount();
    nbSendManage.SendDataLen = cmdAreaLen + len + 1;
    memcpy(nbSendManage.SendBuffer, sendBuff, nbSendManage.SendDataLen);

    NB_TASK_LoadingDataToBeSent(sendBuff, nbSendManage.SendDataLen);
}

/**
 * @brief 发送命令
 *
 * @param [in] cmd
 *
 * @note
 */
static void NB_TASK_Send_cmd(uint8_t cmd)
{
    uint8_t sendBuff[NB_SEND_BUFFER_SIZE] = {0};
    uint8_t cmdLen = 0, sendLen = 0;

    cmdLen = cmdSendInfo[cmd].cmdLen;

    if (cmdLen > sizeof(sendBuff) - 1)
    {
        NB_TASK_LOG_E("Send cmd len overflow");
        return;
    }

    memcpy(sendBuff, cmdSendInfo[cmd].cmdString, cmdLen);
    sendBuff[cmdLen] = '\r';
    sendLen = cmdLen + 1;

    nbSendManage.curSendCmd = cmd;
    nbSendManage.SendStatus = TX_STA_WAIT_ACK;
    nbSendManage.resendCount = 1;
    nbSendManage.resendTimes = cmdSendInfo[cmd].resendTimes;
    nbSendManage.resendInterval = cmdSendInfo[cmd].resendInterval;
    nbSendManage.TimeStamp = OSAL_GetTickCount();
    nbSendManage.SendDataLen = sendLen;
    memcpy(nbSendManage.SendBuffer, sendBuff, nbSendManage.SendDataLen);

    NB_TASK_LoadingDataToBeSent(sendBuff, sendLen);
}
/**
 * @brief 任务投票状态 回调
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_send_ECVOTECHK_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("send data timeout");
    }
}
/**
 * @brief 从低功耗模式退出后， 先发send命令之后，才能读取数据
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_send_test_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        //         if (readDataFlag == SET && recvDataNumber != 0)
        //         {
        // #if !CTM2MREAD_MODE_USED_1
        //             OSAL_EventDelete(COMP_NB, EVENT_NB_READ_NB_BUFFDATA);
        //             OSAL_EventRepeatCreate(COMP_NB, EVENT_NB_READ_NB_BUFFDATA, 100, EVT_PRIORITY_MEDIUM);
        // #endif
        //         }
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("send data timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_CTM2MDEREG);
    }
}
/**
 * @brief 产测信息回调
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_send_ATE_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(pData, "M2SREAD=", strlen("M2SREAD=")) == 0 || memcmp(pData, "M2SWRITE=", strlen("M2SWRITE=")) == 0)
    {
        if (memcmp(pData, "M2SREAD=OK", strlen("M2SREAD=OK")) == 0 || memcmp(pData, "M2SWRITE=OK", strlen("M2SWRITE=OK")) == 0)
        {
            NB_TASK_reset_resend_info();
        }
        else
        {
            NBTask_MessagePublish(len, pData, 0, 0, PUBLISH_APP_ATE);
        }
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("ATE send data timeout");
        NB_TASK_reset_resend_info();
    }
}
/**
 * @brief 发送注销aep平台请求
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_logOut_AEP_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_CTM2MREG);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Log out AEP timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_CGPADDR);
    }
}
static uint8_t NB_TASK_Find(uint8_t *pData, uint8_t len)
{
    uint8_t i;
    for (i = 0; i < len; i++)
    {
        if (pData[i] == ',')
            return i;
    }
    return 0xff;
}
/**
 * @brief 设置读取缓存数据
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_read_data_callback(uint8_t *pData, uint16_t len)
{
    static uint8_t dataFlag = RESET; //成功去读到数据的标志
    uint16_t rxPayloadLen = 0;
    uint8_t CSV_offset = NB_TASK_Find(pData, 4);
// NB_TASK_LOG_I("CSV_offset:%d", CSV_offset);
#if CTM2MREAD_MODE_USED_1
    if (memcmp(&pData[0], "+CTM2MRECV: ", 12) == 0)
    {
        dataFlag = SET;
        rxPayloadLen = len - 12;
        NB_TASK_receive_lot_data_handle(&pData[12], rxPayloadLen);
    }
#else
    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        readEmptyCount++;
        if (readEmptyCount == READ_EMPTY_MAX)
        {
            dataFlag = RESET;
            OSAL_EventDelete(COMP_NB, EVENT_NB_READ_NB_BUFFDATA);
        }
    }
    else if (memcmp(&pData[0], "+CTM2MRECV", 10) == 0)
    {
        readEmptyCount = 0;
        // NB_TASK_LOG_W("readDataFlag:%d,AepOtaMark:%d", readDataFlag, AepOtaMark);
        // if (readDataFlag == SET || AepOtaMark == SET)
        if (dataFlag == RESET)
        {
            dataFlag = SET;
            OSAL_EventRepeatCreate(COMP_NB, EVENT_NB_READ_NB_BUFFDATA, 300, EVT_PRIORITY_MEDIUM);
        }
    }
    else if (CSV_offset != 0xff) //(pData[2] == ',')
    {
        readEmptyCount = 0;
        if (dataFlag == RESET)
        {
            dataFlag = SET;
            OSAL_EventRepeatCreate(COMP_NB, EVENT_NB_READ_NB_BUFFDATA, 300, EVT_PRIORITY_MEDIUM);
        }
        rxPayloadLen = len - (CSV_offset + 1);
        NB_TASK_receive_lot_data_handle(&pData[CSV_offset + 1], rxPayloadLen);
    }
#endif
    else if (memcmp(&pData[0], "+HIB Enter", 10) == 0)
    {
        NB_TASK_LOG_W("NB Enter PSM mode, runStatus:%d", runStatus);
        if (stopIntoPSM == 0)
            NB_TASK_reset_resend_info();
        /* NB 进入低功耗模式 */
        // if (runStatus == NB_STATUS_CONNECTED_AEP)
        // {
        runStatus = NB_STATUS_PSM;
        // }
    }
    else if (memcmp(&pData[0], "+HIB Exit", 9) == 0)
    {
        NB_TASK_LOG_W("NB Exit PSM mode, runStatus:%d", runStatus);
        Device_Write(NB_VIRTUAL_WAKEUP_PIN, NULL, 0, 0);
        wakeup_count = 0;
        OSAL_EventDelete(COMP_NB, EVENT_NB_IO_PULL_UP_WAKE);

        /* NB 退出低功耗模式 */
        if (runStatus == NB_STATUS_PSM)
        {
            NB_TASK_reset_resend_info();
            if (selfCheckFlag == SET)
            {
                NB_TASK_Send_cmd(CURRENT_SEND_CSQ);
            }
            else
            {
                NB_TASK_Send_cmd(CURRENT_SEND_PSM_CLOSE);
            }
        }
        else
        {
            OSAL_EventDelete(COMP_NB, EVENT_NB_POWER_ON);
            NB_TASK_Send_cmd(CURRENT_SEND_AT);
        }
    }
    else if (memcmp(&pData[0], "+CTM2M: reg,0", 13) == 0)
    {
        NB_TASK_LOG_W("AEP register SUCCESS");
        OSAL_EventRepeatCreate(COMP_NB, EVENT_NB_IO_RUN_STATUS_CHECK, NB_RUN_STATUS_CHECK_TIMEOUT, EVT_PRIORITY_MEDIUM);
    }
    else if (memcmp(&pData[0], "+CTM2M: obsrv,0", 15) == 0)
    {
        NB_TASK_LOG_W("AEP communication creat SUCCESS ");
        OSAL_EventDelete(COMP_NB, EVENT_NB_IO_RUN_STATUS_CHECK);
        runStatus = NB_STATUS_CONNECTED_AEP;
#if (!TEST_NB_RF)
        // NB_TASK_Send_cmd(CURRENT_SEND_ECNBIOTRAI);
#endif
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Read timeout");
        // readDataFlag = RESET;
        // readNextFlag = RESET;
        readEmptyCount = READ_EMPTY_MAX;
        OSAL_EventDelete(COMP_NB, EVENT_NB_READ_NB_BUFFDATA);
        // NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}

/**
 * @brief 设置读取缓存数据模式
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_set_readBuff_mode_callback(uint8_t *pData, uint16_t len)
{

    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_ECPURC);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Set readBuff mode timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}

/**
 * @brief 释放RRC连接
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_ECNBIOTRAI_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_PSM_OPEN);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Release RRC link timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_PSM_OPEN);
        // NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}

/**
 * @brief 设置3324定时器时间，重启生效
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_ECCFG_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_PSM_CLOSE);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("ECCFG timer timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}

/**
 * @brief 使能PSM模式回调
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_PSM_enable_callback(uint8_t *pData, uint16_t len)
{

    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_ECCFG);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("PSM enable timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}
/**
 * @brief 查询AEP平台登录状态
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_inquiry_AEP_status_callback(uint8_t *pData, uint16_t len)
{
    static uint8_t regFlag = 0;
    //+CTM2MREG: 1
    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_LOG_W("Aep status:%d, runStatus:%d", regFlag, runStatus);
        NB_TASK_reset_resend_info();

        if (regFlag == 1) //未登录的状态
        {
            regFlag = 0;
            NB_TASK_Send_cmd(CURRENT_SEND_CTM2MREG);
        }
        else if (regFlag == 2) //已登录的状态
        {
            runStatus = NB_STATUS_CONNECTED_AEP;
            NB_TASK_Send_cmd(CURRENT_SEND_TEST);
        }
        else if (regFlag == 3) //已登出的状态
        {
            regFlag = 0;
            runStatus = NB_STATUS_RUNNING;
            NB_TASK_Send_cmd(CURRENT_SEND_CTM2MREG);
        }
    }
    else if ((memcmp(&pData[0], "+CTM2MREG: ", 11) == 0))
    {
        NB_TASK_LOG_I("AEP status:%c", pData[11]);
        if (pData[11] == NWY_AEP_STATUS_ALREADY_LOGIN || pData[11] == NWY_AEP_STATUS_LOADING_LOGIN)
        {
            //已登录的状态
            regFlag = 2;
        }
        else if (pData[11] == NWY_AEP_STATUS_NOT_LOGIN)
        {
            //未登录的状态
            regFlag = 1;
        }
        else if (pData[11] == NWY_AEP_STATUS_ALREADY_LOGOUT)
        {
            //已登出的状态
            regFlag = 3;
        }
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Inquiry AEP status timeout");
        regFlag = RESET;
        NB_TASK_control_nb_status_handle(NB_CONTROL_RESET);
    }
}
/**
 * @brief 登录AEP平台
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_logIn_AEP_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        runStatus = NB_STATUS_CONNECTED_AEP;
        NB_TASK_Send_cmd(CURRENT_SEND_TEST);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Log in AEP timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_CTM2MDEREG);
    }
    else if ((memcmp(&pData[0], "+CTM2M ERROR: 33", len) == 0) || (memcmp(&pData[0], "+CTM2M ERROR: 955", len) == 0))
    {
        NB_TASK_LOG_W("AEP already connected");
        runStatus = NB_STATUS_CONNECTED_AEP;
        NB_TASK_reset_resend_info();
#if (!TEST_NB_RF)
        // NB_TASK_Send_cmd(CURRENT_SEND_ECNBIOTRAI);
#endif
    }
    else if (memcmp(&pData[0], "+CTM2M ERROR: 953", len) == 0)
    {
        NB_TASK_LOG_W("Engine error , RESET");
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
    else if (memcmp(&pData[0], "+CTM2M ERROR: 957", len) == 0)
    {
        NB_TASK_LOG_W("Connect is note use");
        NB_TASK_Send_cmd(CURRENT_SEND_CTM2MDEREG);
    }
}
/**
 * @brief  获取本地时间
 * @note
 */
static ErrorStatus NB_Get_RtcTime(uint32_t *timestamp)
{
    uint8_t temp[6];
    if (Device_Read(vRTC_0, temp, 6, 0) < 0)
    {
        return ERROR;
    }
    *timestamp = OSAL_Time2UTC(temp, 0);
    return SUCCESS;
}

/**
 * @brief  设置本地时间
 * @note
 */
static ErrorStatus NB_Set_RtcTime(uint32_t timestamp)
{
    uint8_t temp[6];
    OSAL_UTC2Time(timestamp, temp);
    return (Device_Write(vRTC_0, temp, 6, 0) < 0) ? ERROR : SUCCESS;
}

/**
 * @brief 从NB模组获取时间
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_Get_Cclk_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_ECSTATUS_RRC);
    }
    else if (memcmp(&pData[0], "+CCLK:", 6) == 0)
    {
        uint8_t i, time[6] = {0};
        uint32_t nb_utc, mcu_utc;
        uint8_t *ptimedata = pData + 10;

        for (i = 0; i < 6; i++)
        {
            NB_TASK_str_to_hex(ptimedata, &time[i], 2);
            ptimedata += 3;
        }

        NB_TASK_LOG_HEX("time", time, 6);

        nb_utc = OSAL_Time2UTC(time, 1);
        NB_TASK_LOG_I("nb_utc  %d", nb_utc);

        NB_Get_RtcTime(&mcu_utc);
        NB_TASK_LOG_I("mcu_utc %d", mcu_utc);
        if (nb_utc > (mcu_utc + 3)) //相差3S以内都不更新时间,且比本地时间小也不更新
        {
            NB_Set_RtcTime(nb_utc);
        }
    }
}
/**
 * @brief 初始化AEP平台地址和端口
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_set_AEP_port_callback(uint8_t *pData, uint16_t len)
{

    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_INQUIRY_CTM2MREG);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Set AEP port timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}

/**
 * @brief 查询IP地址
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_inquiry_IP_status_callback(uint8_t *pData, uint16_t len)
{
    static uint8_t regFlag = RESET;

    if (memcmp(&pData[0], "+CGPADDR: ", 10) == 0)
    {
        //查询成功才注册AEP，否则不注册
        if (len > strlen("+CGPADDR: ,") + 1)
        {
            NB_TASK_LOG_I("IP get success, can regist AEP");
            regFlag = SET;
        }
    }
    else if (memcmp(&pData[0], "ERROR", len) == 0 || memcmp(&pData[0], "+CME ERROR:", len) == 0)
    {
        NB_TASK_LOG_E("IP ERROR");
        regFlag = RESET;
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        if (regFlag == SET)
        {
            regFlag = RESET;
            NB_TASK_reset_resend_info();
            NB_TASK_Send_cmd(CURRENT_SEND_CTM2MSETPM);
        }
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("IP timeout");
        regFlag = RESET;
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}

/**
 * @brief 返回 UE 端关键参数状态
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_inquiry_ECSTATUS_RRC_status_callback(uint8_t *pData, uint16_t len)
{
    static uint8_t nextStepFlag = RESET;
    uint16_t i = 0, j = 0;
    uint16_t start = 0, end = 0;
    uint8_t cutLen = 0, offset = 0;
    // NB_TASK_LOG_D("toltal len:%d", len);

    if (memcmp(&pData[0], "+ECSTATUS: ", 11) == 0)
    {
        offset = 10;
        nextStepFlag = SET;
        for (i = 0; i < len; i++)
        {
            if (pData[i + offset] == ' ')
            {
                start = i;
            }
            else if ((pData[i + offset] == ',' || i == (len - 1)))
            {
                end = i;
                cutLen = end - start - 1; //减去开头空格和末尾的逗号
                // NB_TASK_LOG_D("start:%d, end:%d cutLen:%d", start, end, cutLen);
                // NB_TASK_LOG_D("ECSTATUS cut:%.*s", cutLen, &pData[start + offset + 1]);
                if (memcmp(&pData[start + offset + 1], "CellId:", 7) == 0)
                {
                    nbUeParam.cellIdLen = cutLen - 7;
                    memcpy(nbUeParam.cellId, &pData[start + offset + 1 + 7], nbUeParam.cellIdLen);
                    // NB_TASK_LOG_D("cellId:%.*s", nbUeParam.cellIdLen, nbUeParam.cellId);
                }
            }
        }
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        if (nextStepFlag == SET)
        {
            nextStepFlag = RESET;
            NB_TASK_reset_resend_info();
            NB_TASK_Send_cmd(CURRENT_SEND_ECSTATUS_PHY);
        }
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("ECSTATUS timeout");
        nextStepFlag = RESET;
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}
/**
 * @brief 返回 UE 端关键参数状态
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_inquiry_ECSTATUS_PHY_status_callback(uint8_t *pData, uint16_t len)
{
    static uint8_t nextStepFlag = RESET;
    uint16_t i = 0, j = 0;
    uint16_t start = 0, end = 0;
    uint8_t cutLen = 0, offset = 0;
    // NB_TASK_LOG_D("toltal len:%d", len);

    if (memcmp(&pData[0], "+ECSTATUS: ", 11) == 0)
    {
        offset = 10;
        nextStepFlag = SET;

        for (i = 0; i < len; i++)
        {
            if (pData[i + offset] == ' ')
            {
                start = i;
            }
            else if ((pData[i + offset] == ',' || i == (len - 1)))
            {
                end = i;
                cutLen = end - start - 1; //减去开头空格和末尾的逗号
                // NB_TASK_LOG_D("start:%d, end:%d cutLen:%d", start, end, cutLen);
                //  NB_TASK_LOG_D("ECSTATUS cut:%.*s", cutLen, &pData[start + offset + 1]);
                if (memcmp(&pData[start + offset + 1], "DlEarfcn:", 9) == 0)
                {
                    nbUeParam.dlEarfcnLen = cutLen - 9;
                    memcpy(nbUeParam.dlEarfcn, &pData[start + offset + 1 + 9], nbUeParam.dlEarfcnLen);
                    // NB_TASK_LOG_D("DlEarfcn:%.*s", nbUeParam.dlEarfcnLen, nbUeParam.dlEarfcn);
                }
                else if (memcmp(&pData[start + offset + 1], "PCI:", 4) == 0)
                {
                    nbUeParam.pciLen = cutLen - 4;
                    memcpy(nbUeParam.pci, &pData[start + offset + 1 + 4], nbUeParam.pciLen);
                    // NB_TASK_LOG_D("PCI:%.*s", nbUeParam.pciLen, nbUeParam.pci);
                }
                else if (memcmp(&pData[start + offset + 1], "RSRP:", 5) == 0)
                {
                    nbUeParam.rsrpLen = cutLen - 5;
                    memcpy(nbUeParam.rsrp, &pData[start + offset + 1 + 5], nbUeParam.rsrpLen);
                    // NB_TASK_LOG_D("RSRP:%.*s", nbUeParam.rsrpLen, nbUeParam.rsrp);
                }
                else if (memcmp(&pData[start + offset + 1], "SNR:", 4) == 0)
                {
                    nbUeParam.snrLen = cutLen - 4;
                    memcpy(nbUeParam.snr, &pData[start + offset + 1 + 4], nbUeParam.snrLen);
                    // NB_TASK_LOG_D("SNR:%.*s", nbUeParam.snrLen, nbUeParam.snr);
                }
                else if (memcmp(&pData[start + offset + 1], "TxPower:", 8) == 0)
                {
                    nbUeParam.txPowerLen = cutLen - 8;
                    memcpy(nbUeParam.txPower, &pData[start + offset + 1 + 8], nbUeParam.txPowerLen);
                    // NB_TASK_LOG_D("TxPower:%.*s", nbUeParam.txPowerLen, nbUeParam.txPower);
                    NBTask_MessagePublish(sizeof(nbUeParam), &nbUeParam, 0, 0, PUBLISH_APP_UE);
                }
            }
        }
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        if (nextStepFlag == SET)
        {
            NB_TASK_reset_resend_info();
            nextStepFlag = RESET;
            NB_TASK_Send_cmd(CURRENT_SEND_CGPADDR);
        }
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("ECSTATUS timeout");
        nextStepFlag = RESET;
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}

/**
 * @brief 返回服务小区和邻区信息
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_inquiry_ECBCINFO_status_callback(uint8_t *pData, uint16_t len)
{
    static uint8_t nextStepFlag = RESET;

    if (memcmp(&pData[0], "+ECBCINFOSC: ", 13) == 0)
    {
        nextStepFlag = SET;
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        if (nextStepFlag == SET)
        {
            nextStepFlag = RESET;
            NB_TASK_reset_resend_info();
        }
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("ECBCINFO timeout");
        nextStepFlag = RESET;
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}
/**
 * @brief 查看网络注册情况
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_inquiry_CEREG_status_callback(uint8_t *pData, uint16_t len)
{
    static uint8_t nextStepFlag = RESET;

    if (memcmp(&pData[0], "+CEREG: ", 8) == 0)
    {
        //判断网络注册是否正常， 5为网络正常，其他都不正常
        if (pData[8] == '0' && (pData[10] == '1' || pData[10] == '5'))
        {
            nextStepFlag = SET;
        }
        else
        {
            NB_TASK_LOG_W("CEREG regiset status error");
            nextStepFlag = RESET;
        }
    }
    else if (memcmp(&pData[0], "ERROR", len) == 0 || memcmp(&pData[0], "+CME ERROR:", len) == 0)
    {
        NB_TASK_LOG_E("CEREG ERROR");
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        if (nextStepFlag == SET)
        {
            nextStepFlag = RESET;
            runStatus = NB_STATUS_RUNNING;
            NB_TASK_reset_resend_info();
            NB_TASK_Send_cmd(CURRENT_SEND_CCLK);
        }
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("CEREG timeout");
        nextStepFlag = RESET;
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}

/**
 * @brief 查看网络附着情况
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_inquiry_CGATT_status_callback(uint8_t *pData, uint16_t len)
{
    static uint8_t nextStepFlag = RESET;

    if (memcmp(&pData[0], "+CGATT:", 7) == 0)
    {
        //判断网络是否附着成功
        if (pData[8] == '1')
        {
            nextStepFlag = SET;
        }
        else
        {
            NB_TASK_LOG_E("CGATT status ERROR");
            nextStepFlag = RESET;
        }
    }
    else if (memcmp(&pData[0], "ERROR", len) == 0 || memcmp(&pData[0], "+CME ERROR:", len) == 0)
    {
        NB_TASK_LOG_E("CGATT ERROR");
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        if (nextStepFlag == SET)
        {
            nextStepFlag = RESET;
            NB_TASK_reset_resend_info();
            NB_TASK_Send_cmd(CURRENT_SEND_CEREG);
        }
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("CGATT timeout");
        nextStepFlag = RESET;
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}
/**
 * @brief PSM 低功耗模式打开或者关闭时 会发送指令
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_PSM_status_log_callback(uint8_t *pData, uint16_t len)
{

    if (memcmp(&pData[0], "ERROR", len) == 0 || memcmp(&pData[0], "+CME ERROR:", len) == 0)
    {
        NB_TASK_LOG_E("PSM log  ERROR");
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_CPSMS);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("PSM log  timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}

/**
 * @brief PSM 低功耗模式打开或者关闭回调函数
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_PSM_status_open_PSM_change_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "ERROR", len) == 0 || memcmp(&pData[0], "+CME ERROR:", len) == 0)
    {
        NB_TASK_LOG_E("Psm status change ERROR");
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Psm status change timeout");
        // runStatus = NB_STATUS_PSM;//说明已进入
        // NB_TASK_Send_cmd(CURRENT_SEND_RESET);
        NB_TASK_control_nb_status_handle(NB_CONTROL_RESET);
    }
}
/**
 * @brief PSM 低功耗模式打开或者关闭回调函数
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_PSM_status_close_PSM_change_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "ERROR", len) == 0 || memcmp(&pData[0], "+CME ERROR:", len) == 0)
    {
        NB_TASK_LOG_E("Psm status change ERROR");
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        if (runStatus == NB_STATUS_INIT) //上电初始化时，直接进行下一步骤
        {
            NB_TASK_Send_cmd(CURRENT_SEND_CGATT);
        }
        else if (runStatus == NB_STATUS_PSM) //唤醒时，说明有数据下来
        {
            NB_TASK_Send_cmd(CURRENT_SEND_INQUIRY_CTM2MREG);
        }
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Psm status change timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}

static void NB_TASK_Stop_Into_PSM_change_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_INQUIRY_CTM2MREG);
        stopIntoPSM = 0;
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Stop Into PSM timeout runStatus:%d", runStatus);
        if (runStatus != NB_STATUS_PSM)
        {
            NB_TASK_LOG_E("runStatus err");
        }
        runStatus = NB_STATUS_PSM;
        NB_TASK_control_nb_status_handle(NB_CONTROL_EXIT_PSM);
        stopIntoPSM = 0;
    }
}
/**
 * @brief 查询信号强度
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_inquery_CSQ_callback(uint8_t *pData, uint16_t len)
{
    uint8_t csqValue = 0;
    uint8_t csqStr[2] = {0};
    static uint8_t nextStepFlag = RESET;

    if (memcmp(&pData[0], "+CSQ:", 5) == 0)
    {
        //判断是否有效，否则重发
        memcpy(csqStr, &pData[6], 2);
        csqValue = strtol(csqStr, NULL, 10);
        if (csqValue > 0 && csqValue < 31)
        {
            NB_TASK_LOG_I("Get CSQ:%d", csqValue);
            nextStepFlag = SET;
            NBTask_MessagePublish(sizeof(csqValue), &csqValue, 0, 0, PUBLISH_APP_CSQ);
        }
        else
        {
            NB_TASK_LOG_W("Get CSQ invalid");
        }
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        if (nextStepFlag == SET)
        {
            nextStepFlag = RESET;
            NB_TASK_reset_resend_info();
            if (selfCheckFlag == SET)
            {
                selfCheckFlag = RESET;
                NB_TASK_Send_cmd(CURRENT_SEND_PSM_CLOSE);
            }
            else
            {
                NB_TASK_Send_cmd(CURRENT_SEND_CTM2MRMODE);
            }
        }
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Get CSQ timeout");
        selfCheckFlag = RESET;
        nextStepFlag = RESET;
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}
/**
 * @brief 获取卡ICCID
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_get_ICCID_callback(uint8_t *pData, uint16_t len)
{
    static uint8_t nextStepFlag = RESET;

    if (memcmp(&pData[0], "+ECICCID: ", 10) == 0)
    {
        nextStepFlag = SET;
        NB_TASK_LOG_I("ICCID");
        NBTask_MessagePublish(20, &pData[10], 0, 0, PUBLISH_APP_ICCID);
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        nextStepFlag = RESET;
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_CSQ);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        nextStepFlag = RESET;
        NB_TASK_LOG_W("Get ICCID timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}
/**
 * @brief 获取卡ISIM
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
// static void NB_TASK_get_IMSI_callback(uint8_t *pData, uint16_t len)
// {
//     if (pData[0] - '0' < 10)
//     {
//         NB_TASK_LOG_I("IMSI");
//         //存储或者上报给应用层处理IMSI(暂时用不到)
//     }
//     else if (memcmp(&pData[0], "OK", len) == 0)
//     {
//         NB_TASK_reset_resend_info();
//         NB_TASK_Send_cmd(CURRENT_SEND_CSQ);
//     }
//     else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
//     {
//         NB_TASK_LOG_W("Get IMSI timeout");
//         NB_TASK_Send_cmd(CURRENT_SEND_RESET);
//     }
// }

/**
 * @brief 检查SIM卡状态回调
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_check_SIM_status_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "+CPIN: READY", 12) == 0)
    {
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_ICCID);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("check SIM status timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}
/**
 * @brief 查询模块版本信息回调
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_inqiury_vsrsion_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "+CGMR", 5) == 0)
    {
        //版本号存储或者发送给应用层(模组版本号暂未用到)
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_CPIN);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Inquiry version timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}

/**
 * @brief 查询IMEI回调
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_inqiury_IMEI_callback(uint8_t *pData, uint16_t len)
{
    NB_TASK_LOG_I("IMEI_callback :%.*s", len, pData);
    if (memcmp(&pData[0], "+CGSN:", 6) == 0)
    {
        //设备IMEI号上报给应用层， +CGSN: "861322050005020"只上报数字字符串
        NBTask_MessagePublish(len - 9, &pData[8], 0, 0, PUBLISH_APP_IMEI);
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_CGMR);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_W("Inquiry IMEI timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}

/**
 * @brief 复位命令回调
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_reset_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_E("soft Reset timeout");
        if (runStatus == NB_STATUS_INIT)
        {
            resetCount++;
        }
        else
        {
            resetCount = 0;
        }
        if (resetCount < 3) //硬件复位三次后，超时，不再重新启动模组
        {
            NB_TASK_control_nb_status_handle(NB_CONTROL_RESET);
            OSAL_EventSingleCreate(COMP_NB, EVENT_NB_POWER_ON, NB_POWER_ON_DELAY_TIME, EVT_PRIORITY_MEDIUM);
        }
    }
    else if (memcmp(&pData[0], "OK", len) == 0)
    {
        // resetCount++;
        runStatus = NB_STATUS_INIT;
        NB_TASK_reset_resend_info();
        OSAL_EventDelete(COMP_NB, EVENT_NB_POWER_ON);
        NB_TASK_Send_cmd(CURRENT_SEND_AT);
    }
    else if (memcmp(&pData[0], "+PBREADY", len) == 0)
    {
        // resetCount++;
        OSAL_EventDelete(COMP_NB, EVENT_NB_POWER_ON);
        runStatus = NB_STATUS_INIT;
        NB_TASK_reset_resend_info();
        OSAL_EventDelete(COMP_NB, EVENT_NB_POWER_ON);
        NB_TASK_Send_cmd(CURRENT_SEND_AT);
    }
}
/**
 * @brief
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_CMEE_callback(uint8_t *pData, uint16_t len)
{
    // if (memcmp(&pData[0], "OK", len) == 0)
    // {
    //     NB_TASK_reset_resend_info();
    //     NB_TASK_Send_cmd(CURRENT_SEND_ATE_CLOSE);
    // }
    // else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    // {
    //     NB_TASK_reset_resend_info();
    //     NB_TASK_Send_cmd(CURRENT_SEND_ATE_CLOSE);
    // }
    // else
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_ATE_CLOSE);
    }
}
/**
 * @brief 回显 命令回调函数
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_ATE_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_CGSN);
    }
    else if (memcmp(&pData[0], "ERROR", len) == 0)
    {
        NB_TASK_LOG_E("ATE status change ERROR");
        /* 设置失败，直接重启设备 */
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_E("ATE status change timeout");
        NB_TASK_Send_cmd(CURRENT_SEND_RESET);
    }
}
/**
 * @brief AT 开机命令回调函数
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_at_callback(uint8_t *pData, uint16_t len)
{
    if (memcmp(&pData[0], "OK", len) == 0)
    {
        NB_TASK_reset_resend_info();
        NB_TASK_Send_cmd(CURRENT_SEND_ATE_CLOSE);
        // NB_TASK_Send_cmd(CURRENT_SEND_CMEE);
    }
    else if (memcmp(&pData[0], "+PBREADY", len) == 0)
    {
        NB_TASK_reset_resend_info();
        OSAL_EventDelete(COMP_NB, EVENT_NB_POWER_ON);
        NB_TASK_Send_cmd(CURRENT_SEND_AT);
    }
    else if (memcmp(&pData[0], USER_CMD_TIMEOUT, len) == 0)
    {
        NB_TASK_LOG_E("AT timeout");
        NB_TASK_control_nb_status_handle(NB_CONTROL_RESET);
    }
}

/**
 * @brief
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void NB_TASK_ParseData_handle(uint8_t *pData, uint8_t len)
{
}

/**
 * @brief AT指令重发处理
 *
 *
 * @note
 */
static void NB_TASK_ResendCmdPacket(void)
{
    uint32_t curTimeStamp = 0;

    curTimeStamp = OSAL_GetTickCount();

    if (nbSendManage.SendStatus == TX_STA_WAIT_ACK)
    {
        if (OSAL_PastTime(curTimeStamp, nbSendManage.TimeStamp) > nbSendManage.resendInterval)
        {
            if (nbSendManage.resendCount >= nbSendManage.resendTimes)
            {
                if (cmdSendInfo[nbSendManage.curSendCmd].cb != NULL)
                {
                    nbSendManage.resendCount = 0;
                    nbSendManage.resendTimes = 0;
                    nbSendManage.resendInterval = 0;
                    nbSendManage.SendStatus = TX_STA_IDLE;
                    nbSendManage.SendDataLen = 0;
                    nbSendManage.TimeStamp = 0;
                    memset(nbSendManage.SendBuffer, 0, sizeof(nbSendManage.SendBuffer));
                    cmdSendInfo[nbSendManage.curSendCmd].cb(USER_CMD_TIMEOUT, strlen(USER_CMD_TIMEOUT));
                }
            }
            else
            {
                nbSendManage.TimeStamp = OSAL_GetTickCount();
                NB_TASK_LoadingDataToBeSent(nbSendManage.SendBuffer, nbSendManage.SendDataLen);
                nbSendManage.resendCount++;
            }
        }
    }
}
/**
 * @brief  解析接收的数据包
 * @note
 *
 * @param  pData：数据包地址
 */
static void NB_TASK_ParseRxPacket(uint8_t *pData)
{
    uint8_t statusProcess = RESET;
    if (pData == NULL)
    {
        return;
    }

    NB_TASK_LOG_I("Current send cmd:%d, ackLen:%d", nbSendManage.curSendCmd, CmdPacketRxInfo.protocolCount - 4);
    // NB_TASK_LOG_I("Recv data ack:%.*s", CmdPacketRxInfo.protocolDataCount, CmdPacketRxInfo.protocolDataBuf);
    NB_TASK_LOG_I("Recv AT ack:%.*s", CmdPacketRxInfo.protocolCount, pData);
    // NB_TASK_LOG_I("statusProcess:%d", statusProcess);

    /* 处理命令的ACK */
    if (pData[0] == '\r' && pData[1] == '\n')
    {
        if (memcmp(&pData[2], "ERROR", strlen("ERROR")) == 0 || memcmp(&pData[2], "+CME ERROR:", strlen("+CME ERROR:")) == 0)
        {
            return;
        }
        if (memcmp(&pData[2], "M2SREAD=", strlen("M2SREAD=")) == 0 || memcmp(&pData[2], "M2SWRITE=", strlen("M2SWRITE=")) == 0)
        {
            cmdSendInfo[CURRENT_SEND_ATE].cb(&pData[2], CmdPacketRxInfo.protocolCount - 4);
            return;
        }
        /* 读取+HIB Enter +HIB Exit */
        if ((memcmp(&pData[2], "+HIB Enter", 10) == 0) || (memcmp(&pData[2], "+HIB Exit", 9) == 0))
        {
            cmdSendInfo[CURRENT_SEND_CTM2MREAD].cb(&pData[2], CmdPacketRxInfo.protocolCount - 4);
            statusProcess = SET;
        }
        /* 读取时间*/
        else if (memcmp(&pData[2], "+CCLK:", 6) == 0)
        {
            cmdSendInfo[CURRENT_SEND_CCLK].cb(&pData[2], CmdPacketRxInfo.protocolCount - 4);
            statusProcess = SET;
        }
        /* 读取+CTM2M: reg,0  +CTM2M: obsrv,0 */
        else if ((memcmp(&pData[2], "+CTM2M: reg,0", 13) == 0) || (memcmp(&pData[2], "+CTM2M: obsrv,0", 15) == 0))
        {
            cmdSendInfo[CURRENT_SEND_CTM2MREAD].cb(&pData[2], CmdPacketRxInfo.protocolCount - 4);
            statusProcess = SET;
        }
#if CTM2MREAD_MODE_USED_1
        /* 读取 "+CTM2MRECV:" */
        else if (memcmp(&pData[2], "+CTM2MRECV: ", 12) == 0)
        {
            cmdSendInfo[CURRENT_SEND_CTM2MREAD].cb(&pData[2], CmdPacketRxInfo.protocolCount - 4);
            statusProcess = SET;
        }
#else
        /* 读取 "+CTM2MRECV" */
        else if (memcmp(&pData[2], "+CTM2MRECV", 10) == 0)
        {
            cmdSendInfo[CURRENT_SEND_CTM2MREAD].cb(&pData[2], CmdPacketRxInfo.protocolCount - 4);
            statusProcess = SET;
        }
#endif
        else if (cmdSendInfo[nbSendManage.curSendCmd].cb != NULL && statusProcess == RESET)
        {
            cmdSendInfo[nbSendManage.curSendCmd].cb(&pData[2], CmdPacketRxInfo.protocolCount - 4);
        }

        // NB_TASK_ParseAck_handle(&pData[2], CmdPacketRxInfo.protocolCount - 4); //减去开头和结尾的 \r\n

        memset(CmdPacketRxInfo.protocolBuf, 0, sizeof(CmdPacketRxInfo.protocolBuf));
        CmdPacketRxInfo.protocolCount = 0;
    }

    /* 处理云端发送的数据 */
    if (CmdPacketRxInfo.protocolDataCount != 0)
    {
        /* 读取云端的数据 */
        if (cmdSendInfo[nbSendManage.curSendCmd].cb != NULL && nbSendManage.curSendCmd == CURRENT_SEND_CTM2MREAD)
        {
            cmdSendInfo[nbSendManage.curSendCmd].cb(CmdPacketRxInfo.protocolDataBuf, CmdPacketRxInfo.protocolDataCount);
        }
        memset(CmdPacketRxInfo.protocolDataBuf, 0, sizeof(CmdPacketRxInfo.protocolDataBuf));
        CmdPacketRxInfo.protocolDataCount = 0;
    }
}
/**
 * @brief  从底层环形缓存获取一包数据并解析
 *
 * @note   底层驱动收到数据，会暂存在环形缓存区
 *
 * @return 返回解析后的数据包地址，解析失败返回NULL
 */
static uint8_t *NB_TASK_GetOnePacket(void)
{
    static uint8_t getPacketTimeoutCnt = 0;
    uint8_t tmpData = 0;
    uint16_t dataCount = 0;
    uint8_t flag = 0; //长度特殊处理flag
    uint8_t CRcount = 0;
    uint8_t LFcount = 0;
    uint8_t dataFlag = RESET;
    static uint16_t buffLen = 0;
    static uint16_t buffLenLast = 0;
    uint8_t errdata[NB_RX_BUFF_LEN] = {0};
    uint16_t errdatalen = 0;
    buffLen = OSAL_RingBufferGetValidSize(nbRbHandle);

    if (buffLen == 0)
    {
        return NULL;
    }

    if (buffLen != buffLenLast)
    {
        buffLenLast = buffLen;
        return NULL;
    }
    buffLenLast = 0;

    uint16_t *pCnt = (uint8_t *)&(CmdPacketRxInfo.protocolCount); //解析计数
    uint8_t *protocolBuff = CmdPacketRxInfo.protocolBuf;          //解析缓存

    *pCnt = 0;

    while (OSAL_RingBufferRead(nbRbHandle, &tmpData))
    {
        if (*pCnt == 0)
        {
            if (tmpData == '\r')
            {

                //读取的是NB发送过来的命令执行结果
                protocolBuff[0] = tmpData;
                CRcount++;
                *pCnt = 1;
                if (errdatalen)
                {
                    NB_TASK_LOG_E("head hase errdata:%s", errdata);
                    NB_TASK_LOG_HEX("hex", errdata, errdatalen);
                    errdatalen = 0;
                }
            }
            else if (tmpData >= '0')
            {
                //读取的是数据,读取之后后边再接 命令执行结果 （\r\n OK \r\n）
                // NB_TASK_LOG_E("error head");
                // dataFlag = SET;
                // CmdPacketRxInfo.protocolDataBuf[0] = tmpData;
                *pCnt = 0; //*pCnt = 1;
            }
            errdata[errdatalen++] = tmpData;
        }
        else if (*pCnt > 0)
        {
            if (dataFlag == SET)
            {
                NB_TASK_LOG_E("error receive");
                if (tmpData == '\r')
                {
                    //数据接收完成，记录数据长度
                    CmdPacketRxInfo.protocolDataCount = *pCnt;
                    dataCount = *pCnt;
                    CRcount++;
                    dataFlag = RESET;
                    //开始接收后续的 执行结果， \r开头
                    protocolBuff[0] = tmpData;
                    *pCnt = 1;
                }
                else
                {
                    CmdPacketRxInfo.protocolDataBuf[*pCnt] = tmpData;
                    *pCnt = *pCnt + 1;
                }
            }
            else
            {
                protocolBuff[*pCnt] = tmpData;

                if (tmpData == '\r')
                {
                    CRcount++;
                }
                else if (tmpData == '\n')
                {
                    LFcount++;
                }
                *pCnt = *pCnt + 1;
            }
            // NB_TASK_LOG_D("CRcount:%d, LFcount:%d", CRcount, LFcount);
            if (CRcount == 2 && LFcount == 2)
            {
                // NB_TASK_LOG_HEX("Recv data Packet:", CmdPacketRxInfo.protocolDataBuf, CmdPacketRxInfo.protocolDataCount);
                // NB_TASK_LOG_HEX("Recv cmd Packet:", CmdPacketRxInfo.protocolBuf, CmdPacketRxInfo.protocolCount);
                // NB_TASK_LOG_HEX("Recv AT Packet:", protocolBuff, *pCnt);
                CRcount = 0;
                LFcount = 0;
                dataFlag = RESET;
                // 接收完成
                return protocolBuff;
            }
            else if (CRcount > 2 || LFcount > 2)
            {
                NB_TASK_LOG_W("CRcount:%d, LFcount:%d", CRcount, LFcount);
            }
        }
    }
    if (errdatalen)
    {
        NB_TASK_LOG_E("all data err:%s", errdata);
        NB_TASK_LOG_HEX("hex", errdata, errdatalen);
    }
    return NULL;
}
/**
 * @brief  通信协议事件处理
 *
 * @note   该函数必须循环调用
 */
static void NB_TASK_parse_data_process(void)
{
    if (NB_TASK_GetTxBufferStatus() != 0)
    {
        NB_TASK_ProcessTxBuffer(); //处理发送缓存中的数据
    }
    else
    {
        NB_TASK_ParseRxPacket(NB_TASK_GetOnePacket()); //解析数据
        NB_TASK_ResendCmdPacket();                     //重发命令包
    }
}
/**
 * @brief 发送特殊的NB包，蓝牙转发的
 *
 * @param [in] msg
 *
 * @note
 */
static void NB_Send_specialPacket(uint8_t *msg)
{
    uint8_t sendBufHex[NB_SEND_BUFFER_SIZE] = {0};
    uint8_t sendBufStr[NB_SEND_BUFFER_SIZE * 2] = {0};
    uint8_t sendStrLen = 0;
    uint8_t dataXor = 0;
    NB_ble_forward_protocol_stu_t *pSendMsg = sendBufHex;
    NbSendToLotMsg_t *pmsg = (NbSendToLotMsg_t *)msg;

    pSendMsg->MID = pmsg->MID;
    pSendMsg->start = NB_NOT_DECRYPTION_FRAME_TYPE_START;
    memcpy(pSendMsg->protocolVersion, protocolVersion, sizeof(pSendMsg->protocolVersion));
    pSendMsg->SID = pmsg->SID;
    pSendMsg->dataLen = OSAL_SWAP16(pmsg->len);
    pSendMsg->mType = CMD_TYPE_REPORT;
    memcpy(&pSendMsg->cmd, pmsg->pData, pmsg->len);
    dataXor = NBTask_CalcCheckXor(pSendMsg->protocolVersion, pmsg->len + 7);
    NB_TASK_LOG_D("NB_ProcessMbox: dataXor:%x", dataXor);

    pSendMsg->data[pmsg->len] = dataXor;
    pSendMsg->data[pmsg->len + 1] = NB_NOT_DECRYPTION_FRAME_TYPE_START;
    NB_TASK_LOG_HEX("pSendMsg data:", pSendMsg, sizeof(NB_ble_forward_protocol_stu_t) + pmsg->len + 2);

    sendStrLen = NB_TASK_hex_to_str(sendBufStr, pSendMsg, sizeof(NB_ble_forward_protocol_stu_t) + pmsg->len + 2); // 12为 整个帧 - (cmd+data) 的长度
    NB_TASK_LOG_D("Send ble forward data str:%.*s", sendStrLen, sendBufStr);
    NB_TASK_send_data(sendBufStr, sendStrLen);
}
/**
 * @brief 发送普通的NB包，非蓝牙转发的
 *
 * @param [in] msg
 *
 * @note
 */
static void NB_Send_normalPacket(uint8_t *msg)
{
    uint8_t sendBufHex[NB_SEND_BUFFER_SIZE] = {0};
    uint8_t sendBufStr[NB_SEND_BUFFER_SIZE * 2] = {0};
    uint8_t encryptionData[NB_SEND_BUFFER_SIZE] = {0};
    uint16_t sendStrLen = 0;
    uint8_t dataXor = 0;
    uint16_t encryptionDataLen = 0;
    NbSendToLotMsg_t *pmsg = (NbSendToLotMsg_t *)msg;
    NB_protocol_stu_t *pSendMsg = sendBufHex;

    pSendMsg->MID = pmsg->MID;
    pSendMsg->start = NB_DECRYPTION_FRAME_TYPE_START;
    memcpy(pSendMsg->protocolVersion, protocolVersion, sizeof(pSendMsg->protocolVersion));
    pSendMsg->SID = pmsg->SID;
    pSendMsg->dataLen = pmsg->len;
    pSendMsg->mType = CMD_TYPE_REPORT;

    memcpy(encryptionData, pmsg->pData, pmsg->len);

    //先复制，计算校验值
    memcpy(&pSendMsg->cmd, pmsg->pData, pmsg->len);
    dataXor = NBTask_CalcCheckXor(pSendMsg->protocolVersion, pSendMsg->dataLen + 7);
    NB_TASK_LOG_HEX("MSG data", &pSendMsg->MID, pSendMsg->dataLen + 10);
    NB_TASK_LOG_D("comp dataXor:0x%x", dataXor);

    /* AES128-ECB加密 */
    if (pSendMsg->start == NB_DECRYPTION_FRAME_TYPE_START)
    {
        /* AES128-ECB 加密长度必须是16的倍数，否则补零 */
        if (pSendMsg->dataLen % 16 == 0)
        {
            encryptionDataLen = pSendMsg->dataLen;
        }
        else
        {
            encryptionDataLen = (16 - (pSendMsg->dataLen % 16)) + pSendMsg->dataLen;
        }

        NB_TASK_LOG_HEX("aesKey", aesKey, 16);
        NB_TASK_LOG_HEX("decryptiondata", encryptionData, encryptionDataLen);
        OSAL_Crypto(AES128_ENCRYPTION, encryptionData, encryptionDataLen, &pSendMsg->cmd, aesKey);
        NB_TASK_LOG_HEX("encryptiondata", &pSendMsg->cmd, encryptionDataLen);
    }
    else
    {
        encryptionDataLen = pSendMsg->dataLen;
        memcpy(&pSendMsg->cmd, pmsg->pData, encryptionDataLen);
    }

    pSendMsg->data[encryptionDataLen - 1] = dataXor;
    pSendMsg->dataLen = OSAL_SWAP16(pSendMsg->dataLen);
    pSendMsg->data[encryptionDataLen] = NB_DECRYPTION_FRAME_TYPE_END;
    sendStrLen = NB_TASK_hex_to_str(sendBufStr, pSendMsg, encryptionDataLen + 12); // 12为 整个帧 - (cmd+data) 的长度
    if (pmsg->pData[0] == NB_LKM3_CMD_NET_OPEN_LOCK && AepOtaMark == RESET)
    {
        sendStrLen += sprintf(&sendBufStr[sendStrLen], ",2");
    }

    NB_TASK_LOG_I("Send data str:%.*s", sendStrLen, sendBufStr);
    NB_TASK_send_data(sendBufStr, sendStrLen);
}

/**
 * @brief 处理发送的数据消息
 *
 * @param [in] msg
 *
 * @note
 */
static void NB_AplcSendPacket(uint8_t *msg)
{
    NbSendToLotMsg_t *pPacket = (NbSendToLotMsg_t *)msg;

    NB_TASK_LOG_I("NB_ProcessMbox: MID:%x len:%d", pPacket->MID, pPacket->len + 5);
    if (SUCCESS == OSAL_QueueSend(NB_SendQueue, (void *)msg, (pPacket->len + 5), RESET))
    {
        NB_TASK_LOG_I("NB_SendQueue input success");
        if (NbtxQueueFlag == 0)
        {
            NbtxQueueFlag = 1;
            OSAL_EventRepeatCreate(COMP_NB, EVENT_NB_TX_QUEUE, 20, EVT_PRIORITY_MEDIUM);
        }
    }
    else
    {
        NB_TASK_LOG_E("NB_SendQueue input err");
        NB_Send_normalPacket(msg);
    }
}

const unsigned short crc16_table[256] = {
    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
    0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
    0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
    0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
    0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
    0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
    0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
    0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
    0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
    0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
    0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
    0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
    0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
    0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
    0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
    0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};

int do_crc(int reg_init, uint8_t *data, int length)
{
    int cnt;
    int crc_reg = reg_init;
    for (cnt = 0; cnt < length; cnt++)
    {
        crc_reg = (crc_reg >> 8) ^ crc16_table[(crc_reg ^ *(data++)) & 0xFF];
    }
    return crc_reg;
}
/**
 * @brief 设置 AEP OTA 标志位
 *
 * @param [in] mark         mark=SET:NB 模组禁止休眠
 *
 * @note
 */
static void NB_TASK_Set_AepOtaMark(uint8_t mark)
{
    AepOtaMark = mark;
}
/**
 * @brief 获取 AEP OTA 标志位
 *
 * @param [in] mark         mark=SET:NB 模组禁止休眠
 *
 * @note
 */
static uint8_t NB_TASK_Get_AepOtaMark(void)
{
    return AepOtaMark;
}
/**
 * @brief 发送普通的 AEP OTA包
 *
 * @param [in] msg
 *
 * @note
 */
static void NB_Send_AepOtaPacket(uint8_t *msg)
{
    NbSendToAepOtaMsg_t *pPacket = (NbSendToAepOtaMsg_t *)msg;
    uint8_t paySendHex[NB_RX_BUFF_LEN] = {0xff, 0xfe, 0x01};
    uint8_t paySendStr[NB_RX_BUFF_LEN * 2] = {0};
    AepOta_protocol_stu_t *pAepOtaAck = (AepOta_protocol_stu_t *)&paySendHex;
    uint16_t len = pPacket->len;
    pAepOtaAck->cmd = pPacket->cmd;
    pAepOtaAck->dataLen = OSAL_SWAP16(len);
    memcpy(pAepOtaAck->data, pPacket->pData, len);
    len = len + 8; //数据总长度=dataLen+8
    pAepOtaAck->crc = OSAL_SWAP16(do_crc(0x0000, paySendHex, len));
    len = NB_TASK_hex_to_str(paySendStr, paySendHex, len);

    uint8_t sendBuff[NB_SEND_BUFFER_SIZE * 2] = {0};
    uint16_t cmdAreaLen = 0;
    uint8_t sendCmdType = CURRENT_SEND_CTM2MSEND;

    cmdAreaLen = cmdSendInfo[sendCmdType].cmdLen;
    if (cmdAreaLen + len > (NB_SEND_BUFFER_SIZE * 2))
    {
        NB_TASK_LOG_E("AEP OTA send data len overflow");
        return;
    }

    memcpy(sendBuff, cmdSendInfo[sendCmdType].cmdString, cmdAreaLen);
    memcpy(&sendBuff[cmdAreaLen], paySendStr, len);
    cmdAreaLen += sprintf(&sendBuff[cmdAreaLen + len], ",0");
    sendBuff[cmdAreaLen + len] = '\r';
    nbSendManage.curSendCmd = sendCmdType;
    nbSendManage.SendStatus = TX_STA_WAIT_ACK;
    nbSendManage.resendCount = 1;
    nbSendManage.resendTimes = cmdSendInfo[sendCmdType].resendTimes;
    nbSendManage.resendInterval = cmdSendInfo[sendCmdType].resendInterval;
    nbSendManage.TimeStamp = OSAL_GetTickCount();
    nbSendManage.SendDataLen = cmdAreaLen + len + 1;
    memcpy(nbSendManage.SendBuffer, sendBuff, nbSendManage.SendDataLen);
    NB_TASK_LoadingDataToBeSent(sendBuff, nbSendManage.SendDataLen);
}

/**
 * @brief 处理发送AEP OTA的数据消息
 *
 * @param [in] msg
 *
 * @note
 */
static void NB_AplcSend_AepOtaPacket(uint8_t *msg)
{
    NbSendToAepOtaMsg_t *pPacket = (NbSendToAepOtaMsg_t *)msg;
    NB_TASK_LOG_I("AEP OTA: cmd:%d", pPacket->cmd);
    if (SUCCESS == OSAL_QueueSend(AepOta_TxQueue, (void *)msg, (pPacket->len + 3), RESET))
    {
        NB_TASK_LOG_I("AepOta_TxQueue input success");
        if (AepOtaTxQueueFlag == 0)
        {
            AepOtaTxQueueFlag = 1;
            OSAL_EventRepeatCreate(COMP_NB, EVENT_AEP_OTA_TX_QUEUE, 20, EVT_PRIORITY_MEDIUM);
        }
    }
    else
    {
        NB_TASK_LOG_E("AepOta_TxQueue input err");
        NB_Send_AepOtaPacket(msg);
    }
}
/**
 * @brief 发送普通的 AEP OTA包
 *
 * @param [in] msg
 *
 * @note
 */
static void NB_Send_ATE_Packet(uint8_t *msg)
{
    uint8_t paySendStr[NB_RX_BUFF_LEN * 2] = {0};
    uint8_t sendCmdType = CURRENT_SEND_ATE;
    memcpy(paySendStr, cmdSendInfo[sendCmdType].cmdString, cmdSendInfo[sendCmdType].cmdLen);
    memcpy(paySendStr + strlen(paySendStr), msg, strlen(msg));
    uint16_t len = strlen(paySendStr);

    nbSendManage.curSendCmd = sendCmdType;
    nbSendManage.SendStatus = TX_STA_WAIT_ACK;
    nbSendManage.resendCount = 1;
    nbSendManage.resendTimes = cmdSendInfo[sendCmdType].resendTimes;
    nbSendManage.resendInterval = cmdSendInfo[sendCmdType].resendInterval;
    nbSendManage.TimeStamp = OSAL_GetTickCount();
    nbSendManage.SendDataLen = len;
    memcpy(nbSendManage.SendBuffer, paySendStr, nbSendManage.SendDataLen);
    NB_TASK_LoadingDataToBeSent(nbSendManage.SendBuffer, nbSendManage.SendDataLen);
}
/**
 * @brief  处理邮箱发来的数据
 * @note
 * @return
 */
static void NB_ProcessMbox(uint8_t *msg)
{
    switch (msg[0])
    {
    case NB_CTRL_DATA: //数据
        NB_AplcSendPacket(&msg[1]);
        break;

    case NB_CTRL_PSM_STATUS:
        NB_TASK_LOG_I("NB_ProcessMbox: [0]:%d, [1]:%d", msg[0], msg[1]);
        NB_TASK_control_nb_status_handle(msg[1]);
        break;

    case NB_CTRL_AES_KEY:
        memcpy(aesKey, &msg[1], sizeof(aesKey));
        OSAL_NvWrite(NB_NV_ADDR_AES_KEY, aesKey, 16);

        break;

    case NB_CTRL_GET_CSQ:
        selfCheckFlag = SET;
        if (runStatus == NB_STATUS_CONNECTED_AEP)
        {
            NB_TASK_Send_cmd(CURRENT_SEND_CSQ);
        }
        else
        {
            NB_TASK_control_nb_status_handle(NB_CONTROL_EXIT_PSM);
        }
        break;

    case NB_CTRL_AEP_OTA: // AEP OTA数据
        NB_AplcSend_AepOtaPacket(&msg[1]);
        break;

    case NB_CTRL_ATE: // ATE数据
        NB_Send_ATE_Packet(&msg[1]);
        break;

    default:
        break;
    }
}
/**
 * @brief  串口中断接收回调函数
 * @note
 * @param  data:收到的数据
 * @param  len:数据长度
 */
static void NB_TASK_ReceiveCb(VirtualHardware_enum_t dev, void *data, uint32_t len)
{
    uint8_t *tmp = (uint8_t *)data;

    if (nbRbHandle == NULL)
    {
        return;
    }
    for (uint32_t i = 0; i < len; i++)
    {
        OSAL_RingBufferWrite(nbRbHandle, tmp + i);
    }
}
/**
 * @brief  NB_TASK_Init初始化
 *
 * @note   注册RX回调、创建环形接收缓存
 */
static void NB_TASK_Init(void)
{
    if (nbRbHandle == NULL)
    {
        nbRbHandle = OSAL_RingBufferCreate(NB_RX_BUFF_LEN, 1);
        Device_RegisteredCB(NB_VIRTUAL_UART, NB_TASK_ReceiveCb);
        /* 创建发送队列 */
        NB_SendQueue = OSAL_QueueCreate(NB_SEND_QUEUE_LEN);
        NB_RecvQueue = OSAL_QueueCreate(NB_RECV_QUEUE_LEN);
        AepOta_TxQueue = OSAL_QueueCreate(AEP_OTA_TX_QUEUE_LEN);
    }
}
/**
 * @brief  NB_Task任务函数
 *
 * @note   1.任务函数内不能写阻塞代码
 *         2.任务函数每次运行只处理一个事件
 *
 * @param  event：当前任务的所有事件
 *
 * @return 返回未处理的事件
 */
static uint32_t NB_Task(uint32_t event)
{
    static uint8_t uart_init_flag = RESET;
    if (event & EVENT_SYS_START)
    {
        NB_TASK_LOG_I("NB Task start, flag:%d\r\n", uart_init_flag);
        #ifndef SLAVE_DEVICE 
        SYS_API(NB_TASK_str_to_hex);
        SYS_API(NB_TASK_hex_to_str);
        SYS_API(NB_TASK_get_nb_status);
        SYS_API(Set_BleConnectStatust);
        SYS_API(NB_TASK_receive_ble_convert_data_handle);
        SYS_API(NB_TASK_Set_AepOtaMark);
        SYS_API(NB_TASK_Get_AepOtaMark);
        #endif
        if (uart_init_flag == RESET)
        {
            protocolVersion[0] = (BLE_FIRMWARE_VER >> 16) + '0';
            protocolVersion[1] = (BLE_FIRMWARE_VER >> 8) + '0';
            protocolVersion[2] = (BLE_FIRMWARE_VER >> 0) + '0';
            uart_init_flag = SET;
            NB_TASK_Init();
            NB_TASK_reset_resend_info();
            OSAL_NvRead(NB_NV_ADDR_AES_KEY, aesKey, 16);
        }
        memset(&CmdPacketRxInfo, 0, sizeof(CmdPacketRxInfo));
        Device_Enable(NB_VIRTUAL_UART);
        OSAL_EventRepeatCreate(COMP_NB, EVENT_NB_POLL_DATA, 10, EVT_PRIORITY_MEDIUM);

        /* 如果插拔NB，需要检测NB是否初始化 */
        if (runStatus == NB_STATUS_INIT)
        {
            /*先复位NB */
            NB_TASK_control_nb_status_handle(NB_CONTROL_RESET);
            OSAL_EventSingleCreate(COMP_NB, EVENT_NB_POWER_ON, NB_POWER_ON_DELAY_TIME, EVT_PRIORITY_MEDIUM);
        }
        return (event ^ EVENT_SYS_START);
    }

    /* 系统邮箱事件 */
    if (event & EVENT_SYS_MBOX)
    {
        uint8_t buffer[NB_SEND_BUFFER_SIZE] = {0};
        {
            // if(nbSendManage.SendStatus == TX_STA_IDLE)
            // {
            while (OSAL_MboxAccept(buffer))
            {
                NB_ProcessMbox(buffer);
                // OSAL_EventSingleCreate(COMP_NB, EVENT_SYS_MBOX, 20, EVT_PRIORITY_MEDIUM);
            }
            // }
            // else
            // {
            //     OSAL_EventSingleCreate(COMP_NB, EVENT_SYS_MBOX, 20, EVT_PRIORITY_MEDIUM);
            // }
        }
        return (event ^ EVENT_SYS_MBOX);
    }

    if (event & EVENT_NB_POLL_DATA) //轮询串口事件
    {
        NB_TASK_parse_data_process();
        if (nbSendManage.SendStatus == TX_STA_WAIT_ACK) // TODO:要设置超时，保证系统睡眠
        {
            OSAL_SetTaskStatus(TASK_STA_ACTIVE);
        }
        else
        {
            OSAL_SetTaskStatus(TASK_STA_NORMAL);
        }
        return (event ^ EVENT_NB_POLL_DATA);
    }

    if (event & EVENT_NB_POWER_ON)
    {
        NB_TASK_LOG_I("EVENT_NB_POWER_ON\r\n");
        if (runStatus == NB_STATUS_INIT)
            NB_TASK_Send_cmd(CURRENT_SEND_AT);
        return (event ^ EVENT_NB_POWER_ON);
    }

    /* 读取事件 */
    if (event & EVENT_NB_READ_NB_BUFFDATA)
    {
        if (nbSendManage.SendStatus == TX_STA_IDLE)
        {
            // if (readNextFlag == RESET)
            {
                // readNextFlag = SET;
                NB_TASK_reset_resend_info();
                NB_TASK_Send_cmd(CURRENT_SEND_CTM2MREAD);
            }
            // else
            // {
            //     static uint8_t timeout = 0;
            //     if (++timeout < 3)
            //     {
            //         NB_TASK_LOG_W("readNextFlag:%d\r\n", readNextFlag);
            //     }
            //     else
            //     {
            //         timeout = 0;
            //     }
            //     readNextFlag == RESET;
            // }
        }
        return (event ^ EVENT_NB_READ_NB_BUFFDATA);
    }

    /* WAKE io口拉高 */
    if (event & EVENT_NB_IO_PULL_UP_WAKE)
    {
        wakeup_count++;
        if (wakeup_count % 2 == 0)
        {
            Device_Write(NB_VIRTUAL_WAKEUP_PIN, NULL, 0, 0);
            NB_TASK_LOG_I("wakeup_count:%d", wakeup_count);
            if (wakeup_count == 6)
            {
                wakeup_count = 0;
                OSAL_EventDelete(COMP_NB, EVENT_NB_IO_PULL_UP_WAKE);
                NB_TASK_LOG_E("wakeup timeout");
                if (runStatus == NB_STATUS_PSM)
                {
                    runStatus = NB_STATUS_CONNECTED_AEP;
                    NB_TASK_Send_cmd(CURRENT_SEND_TEST);
                }
            }
        }
        else
        {
            Device_Write(NB_VIRTUAL_WAKEUP_PIN, NULL, 0, 1);
        }
        return (event ^ EVENT_NB_IO_PULL_UP_WAKE);
    }

    /* RESET口拉高 */
    if (event & EVENT_NB_IO_PULL_UP_RESEET)
    {
        Device_Write(NB_VIRTUAL_RESET_PIN, NULL, 0, 0);
        return (event ^ EVENT_NB_IO_PULL_UP_RESEET);
    }

    /* 模组运行状态检查 1s一次， 登录后如果2s内没有建立通讯通道，就登出重试*/
    if (event & EVENT_NB_IO_RUN_STATUS_CHECK)
    {
        static uint8_t count;
        count++;
        if (count % 2 == 0)
        {
            count = 0;
            if (nbSendManage.SendStatus == TX_STA_IDLE && runStatus == NB_STATUS_RUNNING)
            {
                NB_TASK_Send_cmd(CURRENT_SEND_CTM2MDEREG);
            }
        }
        if (runStatus == NB_STATUS_CONNECTED_AEP)
        {
            OSAL_EventDelete(COMP_NB, EVENT_NB_IO_RUN_STATUS_CHECK);
        }

        return (event ^ EVENT_NB_IO_RUN_STATUS_CHECK);
    }

    // /* IO唤醒后，如果2s内没有收到 +HIB Exit, 就直接发送数据读取*/
    // if (event & EVENT_NB_IO_SLEEP_CHECK)
    // {
    //     NB_TASK_LOG_W("NB is not sleep , read data \r\n");
    //     runStatus = NB_STATUS_CONNECTED_AEP;
    //     NB_TASK_send_data("030D05", 6);
    //     return (event ^ EVENT_NB_IO_SLEEP_CHECK);
    // }

    // if (event & EVENT_NB_CONTROL_ENTER_PSM_CHECK) //控制模组进入休眠检查
    // {
    //     NB_TASK_LOG_W("enter PSM check\r\n");
    //     if (AepOtaMark == RESET && readEmptyCount == READ_EMPTY_MAX)
    //     {
    //         OSAL_EventDelete(COMP_NB, EVENT_NB_CONTROL_ENTER_PSM_CHECK);
    //         readDataFlag = RESET;
    //         OSAL_EventDelete(COMP_NB, EVENT_NB_READ_NB_BUFFDATA);
    //         NB_TASK_Send_cmd(CURRENT_SEND_ECNBIOTRAI);
    //     }
    //     return (event ^ EVENT_NB_CONTROL_ENTER_PSM_CHECK);
    // }
    if (event & EVENT_NB_TX_QUEUE)
    {
        static uint8_t stopPSM_flag = 0;
        static uint8_t wakeNB_flag = 0;

        if (runStatus != NB_STATUS_CONNECTED_AEP)
        {
            if (runStatus == NB_STATUS_WAITPSM)
            {
                if (stopPSM_flag == 0)
                {
                    stopPSM_flag = 1;
                    NB_TASK_LOG_W("stop into PSM");
                    if (tx_ctrl_flg)
                    {
                        tx_ctrl_flg = 0;
                        NB_TASK_LOG_E("TX buff not empty !");
                    }
                    NB_TASK_control_nb_status_handle(NB_CONTROL_EXIT_PSM);
                }
            }
            else if (runStatus == NB_STATUS_PSM)
            {
                if (wakeNB_flag == 0)
                {
                    wakeNB_flag = 1;
                    NB_TASK_LOG_W("Wakeup NB");
                    NB_TASK_control_nb_status_handle(NB_CONTROL_EXIT_PSM);
                }
            }
            return (event ^ EVENT_NB_TX_QUEUE);
        }
        else
        {
            wakeNB_flag = 0;
            stopPSM_flag = 0;
            if (nbSendManage.SendStatus == TX_STA_IDLE)
            {
                NbSendToLotMsg_t msg = {0};
                if (OSAL_QueueReceive(NB_SendQueue, &msg) > 0)
                {
                    // 延迟上报开门信息目的为了获取是否有OTA 信息
                    // if (msg.pData[0] == NB_LKM3_CMD_NET_OPEN_LOCK && AepOtaMark == RESET)
                    // {
                    //     static uint8_t cnt = 0;
                    //     cnt++;
                    //     if (cnt >= 50)
                    //     {
                    //         cnt = 0;
                    //         NB_Send_normalPacket(&msg);
                    //     }
                    //     else
                    //     {
                    //         OSAL_QueueSend(NB_SendQueue, &msg, msg.len + 5, SET);
                    //     }
                    // }
                    // else
                    NB_Send_normalPacket(&msg);
                }
                else
                {
                    OSAL_EventDelete(COMP_NB, EVENT_NB_TX_QUEUE);
                    NbtxQueueFlag = 0;
                }
            }
        }
        return (event ^ EVENT_NB_TX_QUEUE);
    }
    if (event & EVENT_AEP_OTA_TX_QUEUE)
    {
        static uint8_t stopPSM_flag = 0;
        static uint8_t wakeNB_flag = 0;

        if (runStatus != NB_STATUS_CONNECTED_AEP)
        {
            if (runStatus == NB_STATUS_WAITPSM)
            {
                if (stopPSM_flag == 0)
                {
                    stopPSM_flag = 1;
                    NB_TASK_LOG_W("stop into PSM1");
                    if (tx_ctrl_flg)
                    {
                        tx_ctrl_flg = 0;
                        NB_TASK_LOG_E("TX buff not empty1!");
                    }
                    NB_TASK_control_nb_status_handle(NB_CONTROL_EXIT_PSM);
                }
            }
            else if (runStatus == NB_STATUS_PSM)
            {
                if (wakeNB_flag == 0)
                {
                    wakeNB_flag = 1;
                    NB_TASK_LOG_W("Wakeup NB1");
                    NB_TASK_control_nb_status_handle(NB_CONTROL_EXIT_PSM);
                }
            }
            return (event ^ EVENT_AEP_OTA_TX_QUEUE);
        }
        else
        {
            wakeNB_flag = 0;
            stopPSM_flag = 0;
            if (nbSendManage.SendStatus == TX_STA_IDLE)
            {
                NbSendToAepOtaMsg_t msg = {0};
                if (OSAL_QueueReceive(AepOta_TxQueue, &msg) > 0)
                {
                    NB_Send_AepOtaPacket(&msg);
                }
                else
                {
                    OSAL_EventDelete(COMP_NB, EVENT_AEP_OTA_TX_QUEUE);
                    AepOtaTxQueueFlag = 0;
                }
            }
        }
        return (event ^ EVENT_AEP_OTA_TX_QUEUE);
    }
    if (event & EVENT_NB_RX_QUEUE)
    {
        if (BleConnectStatus)
        {
            uint16_t publishDataLen;
            uint8_t tmp[NB_RX_BUFF_LEN] = {0};
            NB_protocol_stu_t *pNbPublishiData = (NB_protocol_stu_t *)tmp;
            if (OSAL_QueueReceive(NB_RecvQueue, (void *)pNbPublishiData) > 0)
            {
                publishDataLen = OSAL_SWAP16(pNbPublishiData->dataLen);
                NB_TASK_LOG_I("NB_RecvQueue output success");
                NB_TASK_LOG_I("cmd:%X MID:%X SID:%X len:%d", pNbPublishiData->cmd, pNbPublishiData->MID, pNbPublishiData->SID, publishDataLen);
                NBTask_MessagePublish(publishDataLen, &pNbPublishiData->cmd, pNbPublishiData->SID, pNbPublishiData->MID, PUBLISH_APP_NB_DATA);
            }
            else
            {
                NbRxQueueFlag = 0;
                OSAL_EventDelete(COMP_NB, EVENT_NB_RX_QUEUE);
            }
        }
        return (event ^ EVENT_NB_RX_QUEUE);
    }
    if (event & EVENT_NB_ENTER_PSM)
    {
        if (NbtxQueueFlag == 0 && AepOtaTxQueueFlag == 0 && nbSendManage.SendStatus == TX_STA_IDLE)
        {
            NB_TASK_Enter_PSM();
            OSAL_EventDelete(COMP_NB, EVENT_NB_ENTER_PSM);
        }
        return (event ^ EVENT_NB_ENTER_PSM);
    }
    /* 系统休眠事件 */
    if (event & EVENT_SYS_SLEEP)
    {
        NB_TASK_LOG_I("EVENT_NB_TASK sleep\r\n");
        OSAL_QueueReset(NB_RecvQueue);   //清空队列
        OSAL_QueueReset(NB_SendQueue);   //清空队列
        OSAL_QueueReset(AepOta_TxQueue); //清空队列
        OSAL_SetTaskStatus(TASK_STA_NORMAL);
        OSAL_EventDelete(COMP_NB, EVENT_NB_POLL_DATA);
        Device_Disable(NB_VIRTUAL_UART);
        return (event ^ EVENT_SYS_SLEEP);
    }
    return 0;
}
COMPONENT_TASK_EXPORT(COMP_NB, NB_Task, 16);
